JIT: allow code vectorization and add a copy for shared vars 15/17215/2
Calixte DENIZET [Thu, 17 Sep 2015 15:24:01 +0000 (17:24 +0200)]
Change-Id: I2e272b1171b2edd23c1bd51dc1f587515f69f264

14 files changed:
scilab/modules/ast/Makefile.am
scilab/modules/ast/Makefile.in
scilab/modules/ast/ast.vcxproj
scilab/modules/ast/ast.vcxproj.filters
scilab/modules/ast/includes/jit/JITScalar.hxx
scilab/modules/ast/includes/jit/JITVisitor.hxx
scilab/modules/ast/includes/jit/calls/JITTicToc.hxx [new file with mode: 0644]
scilab/modules/ast/src/cpp/jit/BaseFunctions2.cpp
scilab/modules/ast/src/cpp/jit/JITCall.cpp
scilab/modules/ast/src/cpp/jit/JITCallExp.cpp
scilab/modules/ast/src/cpp/jit/JITForExp.cpp
scilab/modules/ast/src/cpp/jit/JITMemfillExp.cpp
scilab/modules/ast/src/cpp/jit/JITTicToc.cpp [new file with mode: 0644]
scilab/modules/ast/src/cpp/jit/JITVisitor.cpp

index 349c83e..c2b4fb5 100644 (file)
@@ -276,6 +276,7 @@ src/cpp/jit/JITConj.cpp \
 src/cpp/jit/JITFloor.cpp \
 src/cpp/jit/JITCeil.cpp \
 src/cpp/jit/JITRound.cpp \
+src/cpp/jit/JITTicToc.cpp \
 src/cpp/jit/JITAddition.cpp \
 src/cpp/jit/JITSubtraction.cpp \
 src/cpp/jit/JITOpposite.cpp \
index c34e5e0..913bef2 100644 (file)
@@ -379,13 +379,13 @@ am__libsciast_la_SOURCES_DIST = src/c/operations/doublecomplex.c \
        src/cpp/jit/JITReal.cpp src/cpp/jit/JITImag.cpp \
        src/cpp/jit/JITImult.cpp src/cpp/jit/JITConj.cpp \
        src/cpp/jit/JITFloor.cpp src/cpp/jit/JITCeil.cpp \
-       src/cpp/jit/JITRound.cpp src/cpp/jit/JITAddition.cpp \
-       src/cpp/jit/JITSubtraction.cpp src/cpp/jit/JITOpposite.cpp \
-       src/cpp/jit/JITMultiplication.cpp src/cpp/jit/JITEquality.cpp \
-       src/cpp/jit/JITShortcutOps.cpp src/cpp/jit/JITNotEquality.cpp \
-       src/cpp/jit/JITComparisons.cpp src/cpp/jit/JITNegation.cpp \
-       src/cpp/jit/JITRDivision.cpp src/cpp/jit/JITPower.cpp \
-       src/cpp/jit/FunctionSignature.cpp \
+       src/cpp/jit/JITRound.cpp src/cpp/jit/JITTicToc.cpp \
+       src/cpp/jit/JITAddition.cpp src/cpp/jit/JITSubtraction.cpp \
+       src/cpp/jit/JITOpposite.cpp src/cpp/jit/JITMultiplication.cpp \
+       src/cpp/jit/JITEquality.cpp src/cpp/jit/JITShortcutOps.cpp \
+       src/cpp/jit/JITNotEquality.cpp src/cpp/jit/JITComparisons.cpp \
+       src/cpp/jit/JITNegation.cpp src/cpp/jit/JITRDivision.cpp \
+       src/cpp/jit/JITPower.cpp src/cpp/jit/FunctionSignature.cpp \
        src/cpp/jit/ScilabJITEventListener.cpp \
        src/cpp/jit/BaseFunctions1.cpp src/cpp/jit/BaseFunctions2.cpp \
        src/cpp/types/inspector.cpp
@@ -655,6 +655,7 @@ am_libsciast_la_OBJECTS =  \
        src/cpp/jit/libsciast_la-JITFloor.lo \
        src/cpp/jit/libsciast_la-JITCeil.lo \
        src/cpp/jit/libsciast_la-JITRound.lo \
+       src/cpp/jit/libsciast_la-JITTicToc.lo \
        src/cpp/jit/libsciast_la-JITAddition.lo \
        src/cpp/jit/libsciast_la-JITSubtraction.lo \
        src/cpp/jit/libsciast_la-JITOpposite.lo \
@@ -1259,13 +1260,13 @@ libsciast_la_SOURCES = src/c/operations/doublecomplex.c \
        src/cpp/jit/JITReal.cpp src/cpp/jit/JITImag.cpp \
        src/cpp/jit/JITImult.cpp src/cpp/jit/JITConj.cpp \
        src/cpp/jit/JITFloor.cpp src/cpp/jit/JITCeil.cpp \
-       src/cpp/jit/JITRound.cpp src/cpp/jit/JITAddition.cpp \
-       src/cpp/jit/JITSubtraction.cpp src/cpp/jit/JITOpposite.cpp \
-       src/cpp/jit/JITMultiplication.cpp src/cpp/jit/JITEquality.cpp \
-       src/cpp/jit/JITShortcutOps.cpp src/cpp/jit/JITNotEquality.cpp \
-       src/cpp/jit/JITComparisons.cpp src/cpp/jit/JITNegation.cpp \
-       src/cpp/jit/JITRDivision.cpp src/cpp/jit/JITPower.cpp \
-       src/cpp/jit/FunctionSignature.cpp \
+       src/cpp/jit/JITRound.cpp src/cpp/jit/JITTicToc.cpp \
+       src/cpp/jit/JITAddition.cpp src/cpp/jit/JITSubtraction.cpp \
+       src/cpp/jit/JITOpposite.cpp src/cpp/jit/JITMultiplication.cpp \
+       src/cpp/jit/JITEquality.cpp src/cpp/jit/JITShortcutOps.cpp \
+       src/cpp/jit/JITNotEquality.cpp src/cpp/jit/JITComparisons.cpp \
+       src/cpp/jit/JITNegation.cpp src/cpp/jit/JITRDivision.cpp \
+       src/cpp/jit/JITPower.cpp src/cpp/jit/FunctionSignature.cpp \
        src/cpp/jit/ScilabJITEventListener.cpp \
        src/cpp/jit/BaseFunctions1.cpp src/cpp/jit/BaseFunctions2.cpp \
        $(am__append_1)
@@ -2455,6 +2456,8 @@ src/cpp/jit/libsciast_la-JITCeil.lo: src/cpp/jit/$(am__dirstamp) \
        src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
 src/cpp/jit/libsciast_la-JITRound.lo: src/cpp/jit/$(am__dirstamp) \
        src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
+src/cpp/jit/libsciast_la-JITTicToc.lo: src/cpp/jit/$(am__dirstamp) \
+       src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
 src/cpp/jit/libsciast_la-JITAddition.lo: src/cpp/jit/$(am__dirstamp) \
        src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
 src/cpp/jit/libsciast_la-JITSubtraction.lo:  \
@@ -2721,6 +2724,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITSize.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITSqrt.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITSubtraction.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITTicToc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITUnaryOpCall.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITVisitor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITWhileExp.Plo@am__quote@
@@ -4686,6 +4690,13 @@ src/cpp/jit/libsciast_la-JITRound.lo: src/cpp/jit/JITRound.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/jit/libsciast_la-JITRound.lo `test -f 'src/cpp/jit/JITRound.cpp' || echo '$(srcdir)/'`src/cpp/jit/JITRound.cpp
 
+src/cpp/jit/libsciast_la-JITTicToc.lo: src/cpp/jit/JITTicToc.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/jit/libsciast_la-JITTicToc.lo -MD -MP -MF src/cpp/jit/$(DEPDIR)/libsciast_la-JITTicToc.Tpo -c -o src/cpp/jit/libsciast_la-JITTicToc.lo `test -f 'src/cpp/jit/JITTicToc.cpp' || echo '$(srcdir)/'`src/cpp/jit/JITTicToc.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/jit/$(DEPDIR)/libsciast_la-JITTicToc.Tpo src/cpp/jit/$(DEPDIR)/libsciast_la-JITTicToc.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/jit/JITTicToc.cpp' object='src/cpp/jit/libsciast_la-JITTicToc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/jit/libsciast_la-JITTicToc.lo `test -f 'src/cpp/jit/JITTicToc.cpp' || echo '$(srcdir)/'`src/cpp/jit/JITTicToc.cpp
+
 src/cpp/jit/libsciast_la-JITAddition.lo: src/cpp/jit/JITAddition.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/jit/libsciast_la-JITAddition.lo -MD -MP -MF src/cpp/jit/$(DEPDIR)/libsciast_la-JITAddition.Tpo -c -o src/cpp/jit/libsciast_la-JITAddition.lo `test -f 'src/cpp/jit/JITAddition.cpp' || echo '$(srcdir)/'`src/cpp/jit/JITAddition.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/jit/$(DEPDIR)/libsciast_la-JITAddition.Tpo src/cpp/jit/$(DEPDIR)/libsciast_la-JITAddition.Plo
index 41db824..f47d667 100644 (file)
@@ -441,6 +441,7 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\jit\calls\JITSize.hxx" />
     <ClInclude Include="includes\jit\calls\JITSize1.hxx" />
     <ClInclude Include="includes\jit\calls\JITSqrt.hxx" />
+    <ClInclude Include="includes\jit\calls\JITTicToc.hxx" />
     <ClInclude Include="includes\jit\calls\JITUnaryOpCall.hxx" />
     <ClInclude Include="includes\jit\calls\JITZeros.hxx" />
     <ClInclude Include="includes\jit\Cast.hxx" />
@@ -748,6 +749,7 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClCompile Include="src\cpp\jit\JITSize.cpp" />
     <ClCompile Include="src\cpp\jit\JITSqrt.cpp" />
     <ClCompile Include="src\cpp\jit\JITSubtraction.cpp" />
+    <ClCompile Include="src\cpp\jit\JITTicToc.cpp" />
     <ClCompile Include="src\cpp\jit\JITUnaryOpCall.cpp" />
     <ClCompile Include="src\cpp\jit\JITVisitor.cpp" />
     <ClCompile Include="src\cpp\jit\JITWhileExp.cpp" />
index 3a4f351..c5174e9 100644 (file)
     <ClInclude Include="includes\jit\calls\JITZeros.hxx">
       <Filter>Header Files\jit\calls</Filter>
     </ClInclude>
+    <ClInclude Include="includes\jit\calls\JITTicToc.hxx">
+      <Filter>Header Files\jit\calls</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\cpp\ast\debugvisitor.cpp">
     <ClCompile Include="src\cpp\jit\JITMemfillExp.cpp">
       <Filter>Source Files\jit</Filter>
     </ClCompile>
+    <ClCompile Include="src\cpp\jit\JITTicToc.cpp">
+      <Filter>Source Files\jit</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
index 66fb246..fc5722d 100644 (file)
 
 namespace jit
 {
-    class JITScalar : public JITScilabVal
-    {
-
-    protected:
-       
-        llvm::Value * data;
-        bool allocated;
-
-    public:
-
-       JITScalar() : data(nullptr) { }
-       
-        JITScalar(llvm::Value * _data, const bool _allocated, const std::string & name) : data(_data), allocated(_allocated)
-            {
-               if (!name.empty())
-               {
-                   data->setName(name);
-               }
-           }
-
-       bool isValid() const override
-           { 
-               return data != nullptr;
-           }
-       
-        llvm::Value * loadRows(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-        llvm::Value * loadCols(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-        llvm::Value * getRows(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-        llvm::Value * getCols(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-       void setRefCount(llvm::Value * _refCount) override
-           {
-           }
-       
-       void setData(llvm::Value * _data) override
-           {
-               data = _data;
-           }
-
-       void setRows(llvm::Value * _rows) override
-           {
-           }
-
-       void setCols(llvm::Value * _cols) override
-           {
-           }
-
-        void storeRows(JITVisitor & jit, llvm::Value * rows) override
-            {
-
-            }
-
-        void storeCols(JITVisitor & jit, llvm::Value * cols) override
-            {
-
-            }
-
-        bool isScalar() const override
-            {
-                return true;
-            }
-
-        llvm::Value * loadData(JITVisitor & jit) override
-            {
-                if (allocated)
-                {
-                    return jit.getBuilder().CreateAlignedLoad(data, jit.getTySizeInBytes(data));
-                }
-                else
-                {
-                    return data;
-                }
-            }
-
-        llvm::Value * getData(JITVisitor & jit) const override
-            {
-                return data;
-            }
-
-        void storeData(JITVisitor & jit, llvm::Value * _data) override
-            {
-                if (allocated)
-                {
-                    jit.getBuilder().CreateAlignedStore(_data, data, jit.getTySizeInBytes(data));
-                }
-                else
-                {
-                    assert(false && "storeData mustn't be called");
-                }
-            }
-
-        /*types::InternalType::ScilabId getScilabId() const override
-          {
-
-          }
-
-          void setScilabId(const types::InternalType::ScilabId id) override
-          {
-
-          }
-        */
-
-        llvm::Value * loadRefCount(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-        llvm::Value * getRefCount(JITVisitor & jit) const override
-            {
-                return nullptr;
-            }
-
-        void incRefCount(JITVisitor & jit) override
-            {
-
-            }
-
-        void decRefCount(JITVisitor & jit) override
-            {
-
-            }
-    };
+class JITScalar : public JITScilabVal
+{
+
+protected:
+
+    llvm::Value * data;
+    bool allocated;
+
+public:
+
+    JITScalar() : data(nullptr) { }
+
+    JITScalar(llvm::Value * _data, const bool _allocated, const std::string & name) : data(_data), allocated(_allocated)
+    {
+        if (!name.empty())
+        {
+            data->setName(name);
+        }
+    }
+
+    bool isValid() const override
+    {
+        return data != nullptr;
+    }
+
+    llvm::Value * loadRows(JITVisitor & jit) const override
+    {
+        return jit.getConstant<int64_t>(1);
+    }
+
+    llvm::Value * loadCols(JITVisitor & jit) const override
+    {
+        return jit.getConstant<int64_t>(1);
+    }
+
+    llvm::Value * getRows(JITVisitor & jit) const override
+    {
+        return nullptr;
+    }
+
+    llvm::Value * getCols(JITVisitor & jit) const override
+    {
+        return nullptr;
+    }
+
+    void setRefCount(llvm::Value * _refCount) override
+    {
+    }
+
+    void setData(llvm::Value * _data) override
+    {
+        data = _data;
+    }
+
+    void setRows(llvm::Value * _rows) override
+    {
+    }
+
+    void setCols(llvm::Value * _cols) override
+    {
+    }
+
+    void storeRows(JITVisitor & jit, llvm::Value * rows) override
+    {
+
+    }
+
+    void storeCols(JITVisitor & jit, llvm::Value * cols) override
+    {
+
+    }
+
+    bool isScalar() const override
+    {
+        return true;
+    }
+
+    llvm::Value * loadData(JITVisitor & jit) override
+    {
+        if (allocated)
+        {
+            return jit.getBuilder().CreateAlignedLoad(data, jit.getTySizeInBytes(data));
+        }
+        else
+        {
+            return data;
+        }
+    }
+
+    llvm::Value * getData(JITVisitor & jit) const override
+    {
+        return data;
+    }
+
+    void storeData(JITVisitor & jit, llvm::Value * _data) override
+    {
+        if (allocated)
+        {
+            jit.getBuilder().CreateAlignedStore(_data, data, jit.getTySizeInBytes(data));
+        }
+        else
+        {
+            assert(false && "storeData mustn't be called");
+        }
+    }
+
+    /*types::InternalType::ScilabId getScilabId() const override
+      {
+
+      }
+
+      void setScilabId(const types::InternalType::ScilabId id) override
+      {
+
+      }
+    */
+
+    llvm::Value * loadRefCount(JITVisitor & jit) const override
+    {
+        return nullptr;
+    }
+
+    llvm::Value * getRefCount(JITVisitor & jit) const override
+    {
+        return nullptr;
+    }
+
+    void incRefCount(JITVisitor & jit) override
+    {
+
+    }
+
+    void decRefCount(JITVisitor & jit) override
+    {
+
+    }
+};
 }
 
 #endif // __JIT_SCALAR_HXX__
index 592ac75..366d915 100644 (file)
 #include "llvm/Support/TargetRegistry.h"
 //#include "llvm/Support/raw_ostream.h"
 
-#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
 #include "llvm/IR/LegacyPassManager.h"
-#else
-#include "llvm/PassManager.h"
-#endif
 
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Transforms/Scalar.h"
@@ -116,7 +112,7 @@ class EXTERN_AST JITVisitor : public ast::ConstVisitor, public analysis::FBlockE
     llvm::Module * module;
     llvm::TargetMachine * target;
     llvm::ExecutionEngine * engine;
-    //LLVM_FunctionPassManager FPM;
+    llvm::legacy::PassManager MPM;
     llvm::legacy::FunctionPassManager FPM;
     llvm::Function * function;
     llvm::IRBuilder<> builder;
@@ -541,10 +537,11 @@ private:
     llvm::Value * getPtrFromIndex(const ast::CallExp & ce);
     void runOptimizationPasses();
     void compileModule();
+    void cloneSyms(const ast::Exp & e);
     void makeSwitch(const ast::IntSelectExp & e, const std::map<int64_t, ast::Exp *> & map);
     void CreateBr(llvm::BasicBlock * bb);
     void closeEntryBlock();
-    void initFunctionPassManager();
+    void initPassManagers();
 
     static bool InitializeLLVM();
     static llvm::Type * getPtrAsIntTy(llvm::Module & module, llvm::LLVMContext & ctxt);
diff --git a/scilab/modules/ast/includes/jit/calls/JITTicToc.hxx b/scilab/modules/ast/includes/jit/calls/JITTicToc.hxx
new file mode 100644 (file)
index 0000000..8926679
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  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 __JIT_TIC_TOC_HXX__
+#define __JIT_TIC_TOC_HXX__
+
+#include "JITCall.hxx"
+
+namespace jit
+{
+
+class JITTic : public JITCall
+{
+
+public:
+
+    JITTic() { }
+
+    virtual ~JITTic() { }
+
+    virtual bool invoke(const ast::Exp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit);
+};
+
+class JITToc : public JITCall
+{
+
+public:
+
+    JITToc() { }
+
+    virtual ~JITToc() { }
+
+    virtual bool invoke(const ast::Exp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit);
+};
+
+} // namespace jit
+
+#endif // __JIT_TIC_TOC_HXX__
index 63ea509..c6a6d9e 100644 (file)
@@ -10,6 +10,8 @@
 *
 */
 
+#include <chrono>
+
 #include "BaseFunctions.hxx"
 #include "BaseFunctionsMacros2.h"
 #include "base/elem_functions.hxx"
@@ -70,4 +72,16 @@ extern "C"
     {
         return jit::elem::floor<const std::complex<double> &, std::complex<double>>()(z);
     }
+
+    static std::chrono::steady_clock::time_point tictoc_start;
+    void tic()
+    {
+        tictoc_start = std::chrono::steady_clock::now();
+    }
+
+    double toc()
+    {
+        const std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
+        return (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - tictoc_start).count() * 1e-9;
+    }
 }
index 6f137a8..13c2f1e 100644 (file)
 #include "calls/JITFloor.hxx"
 #include "calls/JITCeil.hxx"
 #include "calls/JITRound.hxx"
+#include "calls/JITTicToc.hxx"
 
 namespace jit
 {
 
-    JITCall::FunMap JITCall::funs = init();
+JITCall::FunMap JITCall::funs = init();
 
-    bool JITCall::call(const ast::CallExp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit)
+bool JITCall::call(const ast::CallExp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit)
+{
+    const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e.getName());
+    const symbol::Symbol & funSym = var.getSymbol();
+    const std::wstring & funName = funSym.getName();
+    auto i = funs.find(funName);
+    if (i != funs.end())
     {
-       const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e.getName());
-       const symbol::Symbol & funSym = var.getSymbol();
-       const std::wstring & funName = funSym.getName();
-       auto i = funs.find(funName);
-       if (i != funs.end())
-       {
-           // the function is a "special" call
-           // such as sinus, cosinus, ...
-           return i->second->invoke(e, typesOut, out, jit);
-       }
-       /*else if (types::InternalType * pIT = symbol::Context::getInstance()->get(sym))
-       {
-           if (pIT->isCallable())
-           {
-               switch (pIT->getType())
-               {
-               case types::InternalType::ScilabFunction:
-               case types::InternalType::ScilabMacro:
-               case types::InternalType::ScilabMacroFile:
-               case types::InternalType::ScilabLibrary:
-               default:
-                   return false;
-               }
-           }
-           }*/
-
-       return false;
+        // the function is a "special" call
+        // such as sinus, cosinus, ...
+        return i->second->invoke(e, typesOut, out, jit);
     }
+    /*else if (types::InternalType * pIT = symbol::Context::getInstance()->get(sym))
+    {
+        if (pIT->isCallable())
+        {
+       switch (pIT->getType())
+       {
+       case types::InternalType::ScilabFunction:
+       case types::InternalType::ScilabMacro:
+       case types::InternalType::ScilabMacroFile:
+       case types::InternalType::ScilabLibrary:
+       default:
+           return false;
+       }
+        }
+        }*/
 
+    return false;
+}
 
-    JITCall::FunMap JITCall::init()
-    {
-       FunMap map;
 
-       map.emplace(L"size", std::shared_ptr<JITCall>(new JITSize()));
-       map.emplace(L"zeros", std::shared_ptr<JITCall>(new JITZeros()));
-       map.emplace(L"sin", std::shared_ptr<JITCall>(new JITOptimizedCall1("sin", {{ analysis::TIType::COMPLEX, "csin" }}, llvm::Intrinsic::sin)));
-       map.emplace(L"cos", std::shared_ptr<JITCall>(new JITOptimizedCall1("cos", {{ analysis::TIType::COMPLEX, "ccos" }}, llvm::Intrinsic::cos)));
-       map.emplace(L"exp", std::shared_ptr<JITCall>(new JITOptimizedCall1("exp", {{ analysis::TIType::COMPLEX, "cexp" }}, llvm::Intrinsic::exp)));
-       map.emplace(L"floor", std::shared_ptr<JITCall>(new JITFloor()));
-       map.emplace(L"ceil", std::shared_ptr<JITCall>(new JITCeil()));
-       map.emplace(L"round", std::shared_ptr<JITCall>(new JITRound()));
-       map.emplace(L"atan", std::shared_ptr<JITCall>(new JITOptimizedCall1("atan", {{ analysis::TIType::DOUBLE, "atan" }, { analysis::TIType::COMPLEX, "catan" }})));
-       map.emplace(L"cosh", std::shared_ptr<JITCall>(new JITOptimizedCall1("cosh", {{ analysis::TIType::DOUBLE, "cosh"}, { analysis::TIType::COMPLEX, "ccosh" }})));
-       map.emplace(L"sinh", std::shared_ptr<JITCall>(new JITOptimizedCall1("sinh", {{ analysis::TIType::DOUBLE, "sinh" }, { analysis::TIType::COMPLEX, "csinh" }})));
-       map.emplace(L"erf", std::shared_ptr<JITCall>(new JITOptimizedCall1("erf", {{ analysis::TIType::DOUBLE, "erf" }})));
-       map.emplace(L"erfc", std::shared_ptr<JITCall>(new JITOptimizedCall1("erfc", {{ analysis::TIType::DOUBLE, "erfc" }})));
-       map.emplace(L"erfcx", std::shared_ptr<JITCall>(new JITOptimizedCall1("erfcx")));
-       map.emplace(L"sign", std::shared_ptr<JITCall>(new JITSign()));
-       map.emplace(L"sqrt", std::shared_ptr<JITCall>(new JITSqrt()));
-       map.emplace(L"log", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_E)));
-       map.emplace(L"log2", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_2)));
-       map.emplace(L"log10", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_10)));
-       map.emplace(L"log1p", std::shared_ptr<JITCall>(new JITOptimizedCall1("log1p", {{ analysis::TIType::DOUBLE, "log1p" }})));
-       map.emplace(L"abs", std::shared_ptr<JITCall>(new JITAbs()));
-       map.emplace(L"angle", std::shared_ptr<JITCall>(new JITAngle()));
-       map.emplace(L"real", std::shared_ptr<JITCall>(new JITReal()));
-       map.emplace(L"imag", std::shared_ptr<JITCall>(new JITImag()));
-       map.emplace(L"imult", std::shared_ptr<JITCall>(new JITImult()));
-       map.emplace(L"conj", std::shared_ptr<JITCall>(new JITConj()));
-       return map;
-    }
+JITCall::FunMap JITCall::init()
+{
+    FunMap map;
+
+    map.emplace(L"tic", std::shared_ptr<JITCall>(new JITTic()));
+    map.emplace(L"toc", std::shared_ptr<JITCall>(new JITToc()));
+    map.emplace(L"size", std::shared_ptr<JITCall>(new JITSize()));
+    map.emplace(L"zeros", std::shared_ptr<JITCall>(new JITZeros()));
+    map.emplace(L"sin", std::shared_ptr<JITCall>(new JITOptimizedCall1("sin", {{ analysis::TIType::COMPLEX, "csin" }}, llvm::Intrinsic::sin)));
+    map.emplace(L"cos", std::shared_ptr<JITCall>(new JITOptimizedCall1("cos", {{ analysis::TIType::COMPLEX, "ccos" }}, llvm::Intrinsic::cos)));
+    map.emplace(L"exp", std::shared_ptr<JITCall>(new JITOptimizedCall1("exp", {{ analysis::TIType::COMPLEX, "cexp" }}, llvm::Intrinsic::exp)));
+    map.emplace(L"floor", std::shared_ptr<JITCall>(new JITFloor()));
+    map.emplace(L"ceil", std::shared_ptr<JITCall>(new JITCeil()));
+    map.emplace(L"round", std::shared_ptr<JITCall>(new JITRound()));
+    map.emplace(L"atan", std::shared_ptr<JITCall>(new JITOptimizedCall1("atan", {{ analysis::TIType::DOUBLE, "atan" }, { analysis::TIType::COMPLEX, "catan" }})));
+    map.emplace(L"cosh", std::shared_ptr<JITCall>(new JITOptimizedCall1("cosh", {{ analysis::TIType::DOUBLE, "cosh"}, { analysis::TIType::COMPLEX, "ccosh" }})));
+    map.emplace(L"sinh", std::shared_ptr<JITCall>(new JITOptimizedCall1("sinh", {{ analysis::TIType::DOUBLE, "sinh" }, { analysis::TIType::COMPLEX, "csinh" }})));
+    map.emplace(L"erf", std::shared_ptr<JITCall>(new JITOptimizedCall1("erf", {{ analysis::TIType::DOUBLE, "erf" }})));
+    map.emplace(L"erfc", std::shared_ptr<JITCall>(new JITOptimizedCall1("erfc", {{ analysis::TIType::DOUBLE, "erfc" }})));
+    map.emplace(L"erfcx", std::shared_ptr<JITCall>(new JITOptimizedCall1("erfcx")));
+    map.emplace(L"sign", std::shared_ptr<JITCall>(new JITSign()));
+    map.emplace(L"sqrt", std::shared_ptr<JITCall>(new JITSqrt()));
+    map.emplace(L"log", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_E)));
+    map.emplace(L"log2", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_2)));
+    map.emplace(L"log10", std::shared_ptr<JITCall>(new JITLog(JITLog::BASE_10)));
+    map.emplace(L"log1p", std::shared_ptr<JITCall>(new JITOptimizedCall1("log1p", {{ analysis::TIType::DOUBLE, "log1p" }})));
+    map.emplace(L"abs", std::shared_ptr<JITCall>(new JITAbs()));
+    map.emplace(L"angle", std::shared_ptr<JITCall>(new JITAngle()));
+    map.emplace(L"real", std::shared_ptr<JITCall>(new JITReal()));
+    map.emplace(L"imag", std::shared_ptr<JITCall>(new JITImag()));
+    map.emplace(L"imult", std::shared_ptr<JITCall>(new JITImult()));
+    map.emplace(L"conj", std::shared_ptr<JITCall>(new JITConj()));
+    return map;
+}
 }
 
 /*
index 2c44907..1136e92 100644 (file)
 namespace jit
 {
 
-    void JITVisitor::visit(const ast::CallExp & e)
+void JITVisitor::visit(const ast::CallExp & e)
+{
+    if (e.getName().isSimpleVar())
     {
-       if (e.getName().isSimpleVar())
+        const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e.getName());
+        const analysis::TIType & funty = var.getDecorator().getResult().getType();
+
+        if (funty.type == analysis::TIType::FUNCTION)
         {
-           const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e.getName());
-           const analysis::TIType & funty = var.getDecorator().getResult().getType();
+            if (e.getParent()->isAssignExp())
+            {
+                const ast::AssignExp & ae = *static_cast<const ast::AssignExp *>(e.getParent());
+                if (ae.getLeftExp().isSimpleVar()) // A = ...
+                {
+                    const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar &>(ae.getLeftExp()).getSymbol();
+                    std::vector<analysis::TIType> typesOut;
+                    typesOut.emplace_back(ae.getLeftExp().getDecorator().getResult().getType());
+                    std::vector<JITScilabPtr> out;
+                    out.emplace_back(variables.find(Lsym)->second);
+                    JITCall::call(e, typesOut, out, *this);
+                }
+                else if (ae.getLeftExp().isAssignListExp()) // [A, B] = ...
+                {
+                    ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(ae.getLeftExp());
+                    std::vector<analysis::TIType> typesOut;
+                    std::vector<JITScilabPtr> out;
+                    const ast::exps_t & exps = ale.getExps();
+                    out.reserve(exps.size());
 
-           if (funty.type == analysis::TIType::FUNCTION)
-           {
-               if (e.getParent()->isAssignExp())
-               {
-                   const ast::AssignExp & ae = *static_cast<const ast::AssignExp *>(e.getParent());
-                   if (ae.getLeftExp().isSimpleVar()) // A = ...
-                   {
-                       const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar &>(ae.getLeftExp()).getSymbol();
-                       std::vector<analysis::TIType> typesOut;
-                       typesOut.emplace_back(ae.getLeftExp().getDecorator().getResult().getType());
-                       std::vector<JITScilabPtr> out;
-                       out.emplace_back(variables.find(Lsym)->second);
-                       JITCall::call(e, typesOut, out, *this);
-                   }
-                   else if (ae.getLeftExp().isAssignListExp()) // [A, B] = ...
-                   {
-                       ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(ae.getLeftExp());
-                       std::vector<analysis::TIType> typesOut;
-                       std::vector<JITScilabPtr> out;
-                       const ast::exps_t & exps = ale.getExps();
-                       out.reserve(exps.size());
-                       
-                       for (const auto exp : exps)
-                       {
-                           if (exp->isSimpleVar())
-                           {
-                               const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar *>(exp)->getSymbol();
-                               out.emplace_back(variables.find(Lsym)->second);
-                               typesOut.emplace_back(exp->getDecorator().getResult().getType());
-                           }
-                       }
-                       JITCall::call(e, typesOut, out, *this);
-                   }
-               }
-               else
-               {
-                   std::vector<analysis::TIType> typesOut;
-                   typesOut.emplace_back(e.getDecorator().getResult().getType());
-                   std::vector<JITScilabPtr> out;
-                   JITCall::call(e, typesOut, out, *this);
-                   setResult(out.front());
-               }
-           }
-           else
-           {
-               // We have an extraction
-               llvm::Value * ptr = getPtrFromIndex(e);
-               llvm::Value * val = builder.CreateAlignedLoad(ptr, getTySizeInBytes(getTy(funty)));
-               setResult(getScalar(val, funty.type, false, ""));
-           }
-       }
+                    for (const auto exp : exps)
+                    {
+                        if (exp->isSimpleVar())
+                        {
+                            const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar *>(exp)->getSymbol();
+                            out.emplace_back(variables.find(Lsym)->second);
+                            typesOut.emplace_back(exp->getDecorator().getResult().getType());
+                        }
+                    }
+                    JITCall::call(e, typesOut, out, *this);
+                }
+            }
+            else
+            {
+                std::vector<analysis::TIType> typesOut;
+                typesOut.emplace_back(e.getDecorator().getResult().getType());
+                std::vector<JITScilabPtr> out;
+                JITCall::call(e, typesOut, out, *this);
+                if (!out.empty())
+                {
+                    setResult(out.front());
+                }
+            }
+        }
+        else
+        {
+            // We have an extraction
+            if (e.getDecorator().safe)
+            {
+                if (var.getDecorator().getResult().getType().isscalar())
+                {
+                    setResult(variables.find(var.getSymbol())->second);
+                }
+                else
+                {
+                    llvm::Value * ptr = getPtrFromIndex(e);
+                    llvm::Value * val = builder.CreateAlignedLoad(ptr, getTySizeInBytes(getTy(funty)));
+                    setResult(getScalar(val, funty.type, false, ""));
+                }
+            }
+        }
     }
+}
 
 }
index 2e52f5b..49df35a 100644 (file)
@@ -23,146 +23,6 @@ void JITVisitor::visit(const ast::VarDec & e)
 
 }
 
-/*void JITVisitor::visit(const ast::ForExp & e)
-  {
-  const ast::VarDec & vd = static_cast<const ast::VarDec &>(e.getVardec());
-  // TODO : handle for with an iterator
-  if (vd.getInit().isListExp())
-  {
-  const symbol::Symbol & symIterator = vd.getSymbol();
-  const ast::ListExp & le = static_cast<const ast::ListExp &>(vd.getInit());
-  if (le.getDecorator().getResult().getRange().isValid())
-  {
-  // for i = start:step:end...
-  // is equivalent to for (int64_t i = start; i < end + step; i += step)...
-
-  le.getStart().accept(*this);
-  llvm::Value * start = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-  le.getStep().accept(*this);
-  llvm::Value * step = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-  le.getEnd().accept(*this);
-  llvm::Value * end = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-  end = builder.CreateAdd(end, step);
-
-  llvm::BasicBlock * cur_block = builder.GetInsertBlock();
-  llvm::BasicBlock * condBlock = llvm::BasicBlock::Create(context, "for_cond", function);
-  llvm::BasicBlock * loopBlock = llvm::BasicBlock::Create(context, "for_loop", function);
-  llvm::BasicBlock * afterBlock = llvm::BasicBlock::Create(context, "for_after", function);
-
-  blocks.emplace(condBlock, afterBlock);
-
-  llvm::Value * cmp_i1 = builder.CreateICmpSLT(start, end);
-  builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-  builder.SetInsertPoint(loopBlock);
-  llvm::PHINode * i = builder.CreatePHI(getTy<int64_t>(), 2);
-  i->addIncoming(start, cur_block);
-  JITScilabPtr & it = variables.find(symIterator)->second;
-  it->storeData(*this, i);
-
-  e.getBody().accept(*this);
-  builder.CreateBr(condBlock);
-
-  builder.SetInsertPoint(condBlock);
-  llvm::Value * ipstp_i64 = builder.CreateAdd(i, step);
-  i->addIncoming(ipstp_i64, condBlock);
-  cmp_i1 = builder.CreateICmpSLT(ipstp_i64, end);
-  builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-  builder.SetInsertPoint(afterBlock);
-  }
-  else
-  {
-  const ast::Exp & startE = le.getStart();
-  const ast::Exp & stepE = le.getStep();
-  const ast::Exp & endE = le.getEnd();
-
-  // a lot of for loops are like this: for i=1:N....
-  // start is an integer and step is by default 1 so we can use a classical
-  // loop with integer counter.
-
-  if (startE.isDoubleExp() && stepE.isDoubleExp())
-  {
-  const ast::DoubleExp & startDE = static_cast<const ast::DoubleExp &>(startE);
-  const ast::DoubleExp & stepDE = static_cast<const ast::DoubleExp &>(stepE);
-  int64_t start_i;
-  int64_t step_i;
-  if (analysis::tools::asInteger(startDE.getValue(), start_i) && analysis::tools::asInteger(stepDE.getValue(), step_i))
-  {
-  llvm::Value * start = getConstant(start_i);
-  llvm::Value * step = getConstant(std::abs(step_i));
-  le.getEnd().accept(*this);
-  llvm::Value * end = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-
-  if (step_i > 0)
-  {
-  end = builder.CreateAdd(end, step);
-  }
-  else
-  {
-  end = builder.CreateSub(end, step);
-  }
-
-  llvm::BasicBlock * cur_block = builder.GetInsertBlock();
-  llvm::BasicBlock * condBlock = llvm::BasicBlock::Create(context, "for_cond", function);
-  llvm::BasicBlock * loopBlock = llvm::BasicBlock::Create(context, "for_loop", function);
-  llvm::BasicBlock * afterBlock = llvm::BasicBlock::Create(context, "for_after", function);
-
-  blocks.emplace(condBlock, afterBlock);
-
-  llvm::Value * cmp_i1;
-  if (step_i > 0)
-  {
-  cmp_i1 = builder.CreateICmpSLT(start, end);
-  }
-  else
-  {
-  cmp_i1 = builder.CreateICmpSGT(start, end);
-  }
-  builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-  builder.SetInsertPoint(loopBlock);
-  llvm::PHINode * i = builder.CreatePHI(getTy<int64_t>(), 2);
-  i->addIncoming(start, cur_block);
-  JITScilabPtr & it = variables.find(symIterator)->second;
-  it->storeData(*this, i);
-
-  e.getBody().accept(*this);
-  builder.CreateBr(condBlock);
-
-  builder.SetInsertPoint(condBlock);
-  llvm::Value * ipstp_i64;
-  if (step_i > 0)
-  {
-  ipstp_i64 = builder.CreateAdd(i, step);
-  }
-  else
-  {
-  ipstp_i64 = builder.CreateSub(i, step);
-  }
-
-  i->addIncoming(ipstp_i64, condBlock);
-  if (step_i > 0)
-  {
-  cmp_i1 = builder.CreateICmpSLT(ipstp_i64, end);
-  }
-  else
-  {
-  cmp_i1 = builder.CreateICmpSGT(ipstp_i64, end);
-  }
-  builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-  builder.SetInsertPoint(afterBlock);
-  }
-  }
-  }
-
-  }
-
-
-  // e.getBody().accept(*this);
-  }*/
-
 void JITVisitor::visit(const ast::ForExp & e)
 {
     const ast::VarDec & vd = static_cast<const ast::VarDec &>(e.getVardec());
@@ -426,7 +286,24 @@ void JITVisitor::visit(const ast::ForExp & e)
                 }
             }
 
-            builder.CreateCondBr(cmp_i1, loop, after);
+            bool hasPre = false;
+            if (const analysis::Clone * cl = e.getDecorator().getClone())
+            {
+                if (!cl->get().empty())
+                {
+                    llvm::BasicBlock * pre = llvm::BasicBlock::Create(context, "for_pre", function);
+                    builder.CreateCondBr(cmp_i1, pre, after);
+                    builder.SetInsertPoint(pre);
+                    cloneSyms(e);
+                    builder.CreateBr(loop);
+                    hasPre = true;
+                }
+            }
+
+            if (!hasPre)
+            {
+                builder.CreateCondBr(cmp_i1, loop, after);
+            }
 
             llvm::BasicBlock * cur_block = builder.GetInsertBlock();
 
@@ -507,4 +384,35 @@ void JITVisitor::visit(const ast::ForExp & e)
         }
     }
 }
+
+void JITVisitor::cloneSyms(const ast::Exp & e)
+{
+    if (const analysis::Clone * cl = e.getDecorator().getClone())
+    {
+        if (!cl->get().empty())
+        {
+            llvm::Type * types[] = { getTy<int8_t *>(), getTy<int8_t *>(), getTy<int64_t>(), getTy<int32_t>(), getTy<bool>() };
+            llvm::Value * __memcpy = llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::memcpy, types);
+            llvm::Function * __new = static_cast<llvm::Function *>(module->getOrInsertFunction("new", llvm::FunctionType::get(getTy<int8_t *>(), llvm::ArrayRef<llvm::Type *>(getTy<uint64_t>()), false)));
+            __new->addAttribute(0, llvm::Attribute::NoAlias);
+
+            for (const auto & sym : cl->get())
+            {
+                JITScilabPtr & ptr = variables.find(sym)->second;
+                llvm::Value * x = ptr->loadData(*this);
+                llvm::Value * r = ptr->loadRows(*this);
+                llvm::Value * c = ptr->loadCols(*this);
+                llvm::Value * rc = builder.CreateMul(r, c);
+                llvm::Value * size = builder.CreateMul(rc, getConstant<int64_t>(getTySizeInBytes(x)));
+                llvm::CallInst * dest = builder.CreateCall(__new, size);
+                dest->addAttribute(0, llvm::Attribute::NoAlias);
+                llvm::Value * src = builder.CreateBitCast(x, getTy<int8_t *>());
+                llvm::Value * memcpy_args[] = { dest, src, size, getConstant<int64_t>(getTySizeInBytes(x)), getBool(false) };
+                builder.CreateCall(__memcpy, memcpy_args);
+                ptr->storeData(*this, dest);
+            }
+        }
+    }
+
+}
 }
index 11d0f01..b1f0a26 100644 (file)
@@ -40,107 +40,116 @@ void JITVisitor::visit(const ast::MemfillExp & e)
             isZero = de.getValue() == 0.;
         }
     }
+
     valExp.accept(*this);
     const analysis::TIType & valTy = valExp.getDecorator().getResult().getType();
     llvm::Value * value = Cast::cast<double>(getResult()->loadData(*this), valTy.isintegral() && valTy.issigned(), *this);
-    llvm::Value * r;
-    llvm::Value * c;
-    const unsigned int argSize = args.size();
 
-    switch (argSize)
+    if (e.getDecorator().getResult().getType().isscalar())
     {
-        case 0:
+        setResult(getScalar(value, analysis::TIType::DOUBLE, false, ""));
+        return;
+    }
+    else
+    {
+        llvm::Value * r;
+        llvm::Value * c;
+        const unsigned int argSize = args.size();
+
+        switch (argSize)
         {
-            setResult(getScalar(value, analysis::TIType::DOUBLE, false, ""));
-            return;
+            case 0:
+            {
+                setResult(getScalar(value, analysis::TIType::DOUBLE, false, ""));
+                return;
+            }
+            case 1:
+            {
+                // one arg
+                args.front()->accept(*this);
+                JITScilabPtr & res = getResult();
+                r = res->loadRows(*this);
+                c = res->loadCols(*this);
+                break;
+            }
+            case 2:
+            {
+                // two args
+                args.front()->accept(*this);
+                r = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
+                args.back()->accept(*this);
+                c = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
+                break;
+            }
+            default:
+                return;
         }
-        case 1:
+
+        llvm::Value * rc = builder.CreateMul(r, c);
+        rc = Cast::cast<int64_t>(rc, false, *this);
+        llvm::Value * size = builder.CreateMul(rc, getConstant<int64_t>(sizeof(double)));
+        llvm::Function * __new = static_cast<llvm::Function *>(module.getOrInsertFunction("new", llvm::FunctionType::get(getTy<int8_t *>(), llvm::ArrayRef<llvm::Type *>(getTy<uint64_t>()), false)));
+        __new->addAttribute(0, llvm::Attribute::NoAlias);
+        llvm::CallInst * alloc = builder.CreateCall(__new, size);
+        alloc->addAttribute(0, llvm::Attribute::NoAlias);
+        llvm::Value * dbl_alloc = builder.CreateBitCast(alloc, getTy<double *>());
+
+        if (isZero)
         {
-            // one arg
-            args.front()->accept(*this);
-            JITScilabPtr & res = getResult();
-            r = res->loadRows(*this);
-            c = res->loadCols(*this);
-            break;
+            llvm::Type * memset_types[] = { getTy<int8_t *>(), getTy<uint64_t>() };
+            llvm::Value * __memset = llvm::Intrinsic::getDeclaration(&module, llvm::Intrinsic::memset, memset_types);
+            llvm::Value * memset_args[] = { alloc, getConstant<int8_t>(0), size, getConstant<int32_t>(sizeof(double)), getBool(false) };
+            builder.CreateCall(__memset, memset_args);
         }
-        case 2:
+        else
         {
-            // two args
-            args.front()->accept(*this);
-            r = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-            args.back()->accept(*this);
-            c = Cast::cast<int64_t>(getResult()->loadData(*this), false, *this);
-            break;
-        }
-        default:
-            return;
-    }
+            // just make a loop to fill the array
+            llvm::BasicBlock * cur_block = builder.GetInsertBlock();
+            llvm::BasicBlock * loopBlock = llvm::BasicBlock::Create(context, "memfill_loop", function);
+            llvm::BasicBlock * afterBlock = llvm::BasicBlock::Create(context, "memfill_after", function);
+            llvm::Value * zero_i64 = getConstant<int64_t>(0);
 
-    llvm::Value * rc = builder.CreateMul(r, c);
-    rc = Cast::cast<int64_t>(rc, false, *this);
-    llvm::Value * size = builder.CreateMul(rc, getConstant<int64_t>(sizeof(double)));
-    llvm::Function * __new = static_cast<llvm::Function *>(module.getOrInsertFunction("new", llvm::FunctionType::get(getTy<int8_t *>(), llvm::ArrayRef<llvm::Type *>(getTy<uint64_t>()), false)));
-    __new->addAttribute(0, llvm::Attribute::NoAlias);
-    llvm::CallInst * alloc = builder.CreateCall(__new, size);
-    alloc->addAttribute(0, llvm::Attribute::NoAlias);
-    llvm::Value * dbl_alloc = builder.CreateBitCast(alloc, getTy<double *>());
+            llvm::Value * cmp_i1 = builder.CreateICmpSLT(zero_i64, rc);
+            builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
 
+            builder.SetInsertPoint(loopBlock);
+            llvm::PHINode * i = builder.CreatePHI(getTy<int64_t>(), 2);
+            i->addIncoming(zero_i64, cur_block);
 
-    if (isZero)
-    {
-        llvm::Type * memset_types[] = { getTy<int8_t *>(), getTy<uint64_t>() };
-        llvm::Value * __memset = llvm::Intrinsic::getDeclaration(&module, llvm::Intrinsic::memset, memset_types);
-        llvm::Value * memset_args[] = { alloc, getConstant<int8_t>(0), size, getConstant<int32_t>(sizeof(double)), getBool(false) };
-        builder.CreateCall(__memset, memset_args);
-    }
-    else
-    {
-        // just make a loop to fill the array
-        llvm::BasicBlock * cur_block = builder.GetInsertBlock();
-        llvm::BasicBlock * loopBlock = llvm::BasicBlock::Create(context, "memfill_loop", function);
-        llvm::BasicBlock * afterBlock = llvm::BasicBlock::Create(context, "memfill_after", function);
-        llvm::Value * zero_i64 = getConstant<int64_t>(0);
-
-        llvm::Value * cmp_i1 = builder.CreateICmpSLT(zero_i64, rc);
-        builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-        builder.SetInsertPoint(loopBlock);
-        llvm::PHINode * i = builder.CreatePHI(getTy<int64_t>(), 2);
-        i->addIncoming(zero_i64, cur_block);
-
-        llvm::Value * ptr = builder.CreateGEP(dbl_alloc, i);
-        builder.CreateAlignedStore(value, ptr, sizeof(double));
-        llvm::Value * inc = builder.CreateAdd(i, getConstant<int64_t>(1));
-        i->addIncoming(inc, loopBlock);
-        cmp_i1 = builder.CreateICmpSLT(inc, rc);
-        builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
-
-        builder.SetInsertPoint(afterBlock);
-    }
+            llvm::Value * ptr = builder.CreateGEP(dbl_alloc, i);
+            builder.CreateAlignedStore(value, ptr, sizeof(double));
+            llvm::Value * inc = builder.CreateAdd(i, getConstant<int64_t>(1));
+            i->addIncoming(inc, loopBlock);
+            cmp_i1 = builder.CreateICmpSLT(inc, rc);
+            builder.CreateCondBr(cmp_i1, loopBlock, afterBlock);
 
-    JITScilabPtr Lptr(nullptr);
+            builder.SetInsertPoint(afterBlock);
+        }
 
-    if (e.getParent()->isAssignExp())
-    {
-        const ast::AssignExp & ae = *static_cast<const ast::AssignExp *>(e.getParent());
-        if (ae.getLeftExp().isSimpleVar()) // A = ...
+        JITScilabPtr Lptr(nullptr);
+
+        if (e.getParent()->isAssignExp())
         {
-            const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar &>(ae.getLeftExp()).getSymbol();
-            Lptr = variables.find(Lsym)->second;
+            const ast::AssignExp & ae = *static_cast<const ast::AssignExp *>(e.getParent());
+            if (ae.getLeftExp().isSimpleVar()) // A = ...
+            {
+                const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar &>(ae.getLeftExp()).getSymbol();
+                Lptr = variables.find(Lsym)->second;
+            }
+        }
+        else
+        {
+            Lptr = getTemp(e.getDecorator().getResult().getTempId());
         }
-    }
-    else
-    {
-        Lptr = getTemp(e.getDecorator().getResult().getTempId());
-    }
 
-    if (Lptr.get())
-    {
-        Lptr->storeData(*this, dbl_alloc);
-        Lptr->storeRows(*this, r);
-        Lptr->storeCols(*this, c);
-    }
+        if (Lptr.get())
+        {
+            Lptr->storeData(*this, dbl_alloc);
+            Lptr->storeRows(*this, r);
+            Lptr->storeCols(*this, c);
+        }
 
-    setResult(Lptr);
+        setResult(Lptr);
+    }
 }
 }
diff --git a/scilab/modules/ast/src/cpp/jit/JITTicToc.cpp b/scilab/modules/ast/src/cpp/jit/JITTicToc.cpp
new file mode 100644 (file)
index 0000000..fd3dfcc
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  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 "JITScalars.hxx"
+#include "JITArrayofs.hxx"
+#include "JITVisitor.hxx"
+#include "calls/JITTicToc.hxx"
+
+namespace jit
+{
+
+bool JITTic::invoke(const ast::Exp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit)
+{
+    const std::vector<llvm::Type *> types;
+    const std::vector<llvm::Value *> args;
+    llvm::FunctionType * funtype = llvm::FunctionType::get(jit.getTy<void>(), types, false);
+    llvm::Function * toCall = static_cast<llvm::Function *>(jit.getModule().getOrInsertFunction("tic", funtype));
+    llvm::CallInst * ret = jit.getBuilder().CreateCall(toCall, args);
+    ret->setTailCall(true);
+
+    return true;
+}
+
+bool JITToc::invoke(const ast::Exp & e, const std::vector<analysis::TIType> & typesOut, std::vector<JITScilabPtr> & out, JITVisitor & jit)
+{
+    const std::vector<llvm::Type *> types;
+    const std::vector<llvm::Value *> args;
+    llvm::FunctionType * funtype = llvm::FunctionType::get(jit.getTy<double>(), types, false);
+    llvm::Function * toCall = static_cast<llvm::Function *>(jit.getModule().getOrInsertFunction("toc", funtype));
+    llvm::CallInst * ret = jit.getBuilder().CreateCall(toCall, args);
+    ret->setTailCall(true);
+
+    if (out.empty())
+    {
+        out.emplace_back(jit.getScalar(ret, analysis::TIType::DOUBLE, false, ""));
+    }
+    else
+    {
+        out.front()->storeData(jit, ret);
+    }
+
+    return true;
+}
+
+} // namespace jit
index 353f284..b800851 100644 (file)
 
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+
+//#undef NDEBUG
+//#include "llvm/Support/Debug.h"
 
 #include "MemoryManager.hxx"
 #include "JITScalars.hxx"
@@ -33,6 +37,7 @@ JITVisitor::JITVisitor(const analysis::AnalysisVisitor & _analysis) : ast::Const
     module(new llvm::Module("JIT", context)),
     target(nullptr),
     engine(InitializeEngine(module, &target)),
+    MPM(),
     FPM(module),
     function(nullptr),
     builder(context),
@@ -53,7 +58,10 @@ JITVisitor::JITVisitor(const analysis::AnalysisVisitor & _analysis) : ast::Const
     _result(nullptr),
     cpx_rvalue(nullptr)
 {
-    initFunctionPassManager();
+    MPM.add(llvm::createTargetTransformInfoWrapperPass(target->getTargetIRAnalysis()));
+    FPM.add(llvm::createTargetTransformInfoWrapperPass(target->getTargetIRAnalysis()));
+    initPassManagers();
+
     //std::wcerr << "Map size=" << MemoryManager::getMapSize() << std::endl;
 }
 
@@ -79,11 +87,13 @@ void JITVisitor::runOptimizationPasses()
     std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
 #endif
 
-    for (llvm::Function & function : *module)
+    FPM.doInitialization();
+    for (llvm::Function & f : *module)
     {
-        FPM.run(function);
+        FPM.run(f);
     }
     FPM.doFinalization();
+    MPM.run(*module);
 
 #if TIME_LLVM == 1
     std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
@@ -272,7 +282,6 @@ void JITVisitor::visit(const ast::CellCallExp & e)
 
 void JITVisitor::visit(const ast::AssignExp & e)
 {
-
     if (e.getLeftExp().isSimpleVar()) // A = ...
     {
         const ast::Exp & rExp = e.getRightExp();
@@ -295,11 +304,10 @@ void JITVisitor::visit(const ast::AssignExp & e)
         {
             rExp.accept(*this);
             // A = foo(...)...
-            if (!rExp.isCallExp() || !rExp.isMemfillExp())
+            if (!rExp.isCallExp())// && !rExp.isMemfillExp())
             {
                 JITScilabPtr & Lvalue = variables.find(Lsym)->second;
                 JITScilabPtr & Rvalue = getResult();
-                module->dump();
                 Lvalue->storeRows(*this, Rvalue->loadRows(*this));
                 Lvalue->storeCols(*this, Rvalue->loadCols(*this));
                 Lvalue->storeData(*this, Rvalue->loadData(*this));
@@ -325,12 +333,28 @@ void JITVisitor::visit(const ast::AssignExp & e)
              *    ii) A(I) = fun(I): in the general case we should try to devectorize the expression
              *    iii) A(i) = B(i): no problem
              */
-            const symbol::Symbol & symL = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
+            const ast::SimpleVar & var = static_cast<ast::SimpleVar &>(ce.getName());
+            const symbol::Symbol & symL = var.getSymbol();
             if (e.getDecorator().safe && ce.getDecorator().getResult().getType().isscalar())
             {
-                llvm::Value * ptr = getPtrFromIndex(ce);
-                e.getRightExp().accept(*this);
-                builder.CreateStore(getResult()->loadData(*this), ptr);
+                const analysis::TIType & ty = var.getDecorator().getResult().getType();
+                if (ty.isscalar())
+                {
+                    JITScilabPtr & Lvalue = variables.find(symL)->second;
+                    e.getRightExp().accept(*this);
+                    JITScilabPtr & Rvalue = getResult();
+                    Lvalue->storeData(*this, Rvalue->loadData(*this));
+                    if (ty.type == analysis::TIType::COMPLEX)
+                    {
+                        Lvalue->storeImag(*this, Rvalue->loadImag(*this));
+                    }
+                }
+                else
+                {
+                    llvm::Value * ptr = getPtrFromIndex(ce);
+                    e.getRightExp().accept(*this);
+                    builder.CreateStore(getResult()->loadData(*this), ptr);
+                }
             }
         }
     }
@@ -645,9 +669,8 @@ void JITVisitor::action(analysis::FunctionBlock & fblock)
         }
     }
 
-    llvm::FunctionType * ftype = llvm::FunctionType::get(retTy, llvm::ArrayRef<llvm::Type *>(args), /* isVarArgs */ false);
+    llvm::FunctionType * ftype = llvm::FunctionType::get(retTy, args, /* isVarArgs */ false);
     //function = llvm::cast<llvm::Function>(module.getOrInsertFunction("jit_" + name, ftype));
-    std::cerr << "NAME=" << _name << std::endl;
     function = llvm::cast<llvm::Function>(module->getOrInsertFunction(_name, ftype));
 
     entryBlock = llvm::BasicBlock::Create(context, "EntryBlock", function);
@@ -1035,8 +1058,6 @@ void JITVisitor::makeCall(const std::wstring & name, const std::vector<types::In
 
     compileModule();
 
-    std::wcerr << "main ptr: " << (void *)(intptr_t)engine->getFunctionAddress("main") << std::endl;
-
     start = std::chrono::steady_clock::now();
     reinterpret_cast<void (*)()>(engine->getFunctionAddress("main"))();
     end = std::chrono::steady_clock::now();
@@ -1048,7 +1069,6 @@ void JITVisitor::makeCall(const std::wstring & name, const std::vector<types::In
     {
         if (ty.type == analysis::TIType::COMPLEX)
         {
-            //std::wcerr << "WTF=" << llvmOuts.back().data.cpx[1] << std::endl;
             pIT = new types::Double(llvmOuts.back().data.cpx[0], llvmOuts.back().data.cpx[1]);
         }
         else if (ty.type == analysis::TIType::DOUBLE)
@@ -1125,7 +1145,7 @@ llvm::FunctionType * JITVisitor::getFunctionType(const analysis::TIType & out, c
         }
     }
 
-    return llvm::FunctionType::get(out_ty, llvm::ArrayRef<llvm::Type *>(args), false);
+    return llvm::FunctionType::get(out_ty, args, false);
 }
 
 llvm::Type * JITVisitor::getPtrAsIntTy(llvm::Module & module, llvm::LLVMContext & ctxt)
@@ -1148,19 +1168,10 @@ bool JITVisitor::InitializeLLVM()
     llvm::initializeVectorization(Registry);
     llvm::initializeIPO(Registry);
     llvm::initializeAnalysis(Registry);
-    llvm::initializeIPA(Registry);
     llvm::initializeTransformUtils(Registry);
     llvm::initializeInstCombine(Registry);
     llvm::initializeInstrumentation(Registry);
     llvm::initializeTarget(Registry);
-    // For codegen passes, only passes that do IR to IR transformation are
-    // supported.
-    llvm::initializeCodeGenPreparePass(Registry);
-    llvm::initializeAtomicExpandPass(Registry);
-    llvm::initializeRewriteSymbolsPass(Registry);
-    llvm::initializeWinEHPreparePass(Registry);
-    llvm::initializeDwarfEHPreparePass(Registry);
-    //llvm::initializeSjLjEHPreparePass(Registry);
 
     llvm::InitializeNativeTarget();
     llvm::InitializeNativeTargetAsmPrinter();
@@ -1174,7 +1185,7 @@ llvm::ExecutionEngine * JITVisitor::InitializeEngine(llvm::Module * module, llvm
     std::string err;
     llvm::TargetOptions opt;
     llvm::EngineBuilder eb(std::move(std::unique_ptr<llvm::Module>(module)));
-    eb.setEngineKind(llvm::EngineKind::JIT).setMCJITMemoryManager(std::move(std::unique_ptr<llvm::RTDyldMemoryManager> {new MemoryManager()})).setOptLevel(llvm::CodeGenOpt::Aggressive).setErrorStr(&err);
+    eb.setEngineKind(llvm::EngineKind::JIT).setMCJITMemoryManager(std::move(std::unique_ptr<llvm::RTDyldMemoryManager> {new MemoryManager()})).setOptLevel(llvm::CodeGenOpt::Aggressive).setErrorStr(&err).setMCPU(llvm::sys::getHostCPUName());
 
     llvm::TargetMachine * tm = eb.selectTarget();
     llvm::Triple triple(llvm::sys::getProcessTriple());
@@ -1193,18 +1204,24 @@ llvm::ExecutionEngine * JITVisitor::InitializeEngine(llvm::Module * module, llvm
     return engine;
 }
 
-void JITVisitor::initFunctionPassManager()
+void JITVisitor::initPassManagers()
 {
     llvm::PassManagerBuilder PMB;
-    PMB.OptLevel = 3;
+    PMB.OptLevel = 2;
     PMB.SizeLevel = 0;
+    /*PMB.BBVectorize = true;
     PMB.LoopVectorize = true;
     PMB.SLPVectorize = true;
     PMB.LoadCombine = true;
-    PMB.DisableUnrollLoops = false;
-    PMB.DisableGVNLoadPRE = false;
+    PMB.DisableUnrollLoops = false;*/
+    //PMB.RerollLoops = false;
+    //PMB.DisableGVNLoadPRE = true;
+    PMB.DisableUnitAtATime = false;
     PMB.populateFunctionPassManager(FPM);
-    FPM.doInitialization();
+    PMB.populateModulePassManager(MPM);
+
+    //llvm::setCurrentDebugType("loop-vectorize");
+    //llvm::DebugFlag = true;
 }
 
 }