JIT: fix link problems with function calls 01/15001/2
Calixte DENIZET [Thu, 7 Aug 2014 12:30:45 +0000 (14:30 +0200)]
Change-Id: If67e561a49420c53b32ce1b0981425d68324eba1

scilab/modules/ast/Makefile.am
scilab/modules/ast/Makefile.in
scilab/modules/ast/includes/jit/JITVisitor.hxx
scilab/modules/ast/includes/jit/ScilabJITTraits.hxx
scilab/modules/ast/includes/operations/types_addition.hxx
scilab/modules/ast/src/cpp/jit/GlobalCFunctions.cpp [new file with mode: 0644]
scilab/modules/ast/src/cpp/jit/JITVisitor.cpp
scilab/modules/ast/src/cpp/jit/operations.cpp

index 3e96db9..6772b9c 100644 (file)
@@ -104,7 +104,8 @@ libsciast_la_SOURCES = \
     src/cpp/system_env/warningmode.cpp \
     src/cpp/jit/JITVisitor.cpp \
     src/cpp/jit/JITValues.cpp \
-    src/cpp/jit/operations.cpp
+    src/cpp/jit/operations.cpp \
+    src/cpp/jit/GlobalCFunctions.cpp
 
 if ENABLE_DEBUG
 libsciast_la_SOURCES += src/cpp/types/inspector.cpp
index 7c99bae..c03e824 100644 (file)
@@ -227,7 +227,7 @@ am__libsciast_la_SOURCES_DIST = src/cpp/ast/runvisitor.cpp \
        src/cpp/system_env/formatmode.cpp \
        src/cpp/system_env/warningmode.cpp src/cpp/jit/JITVisitor.cpp \
        src/cpp/jit/JITValues.cpp src/cpp/jit/operations.cpp \
-       src/cpp/types/inspector.cpp
+       src/cpp/jit/GlobalCFunctions.cpp src/cpp/types/inspector.cpp
 am__dirstamp = $(am__leading_dot)dirstamp
 @ENABLE_DEBUG_TRUE@am__objects_1 =  \
 @ENABLE_DEBUG_TRUE@    src/cpp/types/libsciast_la-inspector.lo
@@ -321,7 +321,8 @@ am_libsciast_la_OBJECTS = src/cpp/ast/libsciast_la-runvisitor.lo \
        src/cpp/system_env/libsciast_la-warningmode.lo \
        src/cpp/jit/libsciast_la-JITVisitor.lo \
        src/cpp/jit/libsciast_la-JITValues.lo \
-       src/cpp/jit/libsciast_la-operations.lo $(am__objects_1)
+       src/cpp/jit/libsciast_la-operations.lo \
+       src/cpp/jit/libsciast_la-GlobalCFunctions.lo $(am__objects_1)
 libsciast_la_OBJECTS = $(am_libsciast_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -766,7 +767,7 @@ libsciast_la_SOURCES = src/cpp/ast/runvisitor.cpp \
        src/cpp/system_env/formatmode.cpp \
        src/cpp/system_env/warningmode.cpp src/cpp/jit/JITVisitor.cpp \
        src/cpp/jit/JITValues.cpp src/cpp/jit/operations.cpp \
-       $(am__append_1)
+       src/cpp/jit/GlobalCFunctions.cpp $(am__append_1)
 libsciast_la_CPPFLAGS = \
        -Iincludes/ast \
        -Iincludes/exps \
@@ -1429,6 +1430,9 @@ src/cpp/jit/libsciast_la-JITValues.lo: src/cpp/jit/$(am__dirstamp) \
        src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
 src/cpp/jit/libsciast_la-operations.lo: src/cpp/jit/$(am__dirstamp) \
        src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
+src/cpp/jit/libsciast_la-GlobalCFunctions.lo:  \
+       src/cpp/jit/$(am__dirstamp) \
+       src/cpp/jit/$(DEPDIR)/$(am__dirstamp)
 src/cpp/types/libsciast_la-inspector.lo:  \
        src/cpp/types/$(am__dirstamp) \
        src/cpp/types/$(DEPDIR)/$(am__dirstamp)
@@ -1477,6 +1481,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/ast/$(DEPDIR)/libsciast_la-runvisitor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/ast/$(DEPDIR)/libsciast_la-shortcutvisitor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/ast/$(DEPDIR)/libsciast_la-visitor_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-GlobalCFunctions.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/jit/$(DEPDIR)/libsciast_la-JITValues.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-operations.Plo@am__quote@
@@ -2236,6 +2241,13 @@ src/cpp/jit/libsciast_la-operations.lo: src/cpp/jit/operations.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-operations.lo `test -f 'src/cpp/jit/operations.cpp' || echo '$(srcdir)/'`src/cpp/jit/operations.cpp
 
+src/cpp/jit/libsciast_la-GlobalCFunctions.lo: src/cpp/jit/GlobalCFunctions.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-GlobalCFunctions.lo -MD -MP -MF src/cpp/jit/$(DEPDIR)/libsciast_la-GlobalCFunctions.Tpo -c -o src/cpp/jit/libsciast_la-GlobalCFunctions.lo `test -f 'src/cpp/jit/GlobalCFunctions.cpp' || echo '$(srcdir)/'`src/cpp/jit/GlobalCFunctions.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/jit/$(DEPDIR)/libsciast_la-GlobalCFunctions.Tpo src/cpp/jit/$(DEPDIR)/libsciast_la-GlobalCFunctions.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/jit/GlobalCFunctions.cpp' object='src/cpp/jit/libsciast_la-GlobalCFunctions.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-GlobalCFunctions.lo `test -f 'src/cpp/jit/GlobalCFunctions.cpp' || echo '$(srcdir)/'`src/cpp/jit/GlobalCFunctions.cpp
+
 src/cpp/types/libsciast_la-inspector.lo: src/cpp/types/inspector.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/types/libsciast_la-inspector.lo -MD -MP -MF src/cpp/types/$(DEPDIR)/libsciast_la-inspector.Tpo -c -o src/cpp/types/libsciast_la-inspector.lo `test -f 'src/cpp/types/inspector.cpp' || echo '$(srcdir)/'`src/cpp/types/inspector.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/types/$(DEPDIR)/libsciast_la-inspector.Tpo src/cpp/types/$(DEPDIR)/libsciast_la-inspector.Plo
index f4bec52..08efb90 100644 (file)
@@ -89,6 +89,11 @@ public:
         return context;
     }
 
+    inline llvm::Module & getModule()
+    {
+        return module;
+    }
+
     inline llvm::IRBuilder<> & getBuilder()
     {
         return builder;
index 0445059..9ae7845 100644 (file)
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/PassManager.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Transforms/Scalar.h"
 
 namespace jit
 {
@@ -237,6 +247,15 @@ struct _get_llvm_ty<int>
 };
 
 template<>
+struct _get_llvm_ty<uint32_t>
+{
+    inline static llvm::Type * get(llvm::LLVMContext & ctxt)
+    {
+        return llvm::Type::getInt32Ty(ctxt);
+    }
+};
+
+template<>
 struct _get_llvm_ty<long long>
 {
     inline static llvm::Type * get(llvm::LLVMContext & ctxt)
@@ -246,6 +265,15 @@ struct _get_llvm_ty<long long>
 };
 
 template<>
+struct _get_llvm_ty<long>
+{
+    inline static llvm::Type * get(llvm::LLVMContext & ctxt)
+    {
+        return llvm::IntegerType::get(ctxt, sizeof(long) * 8);
+    }
+};
+
+template<>
 struct _get_llvm_ty<void>
 {
     inline static llvm::Type * get(llvm::LLVMContext & ctxt)
@@ -261,40 +289,40 @@ inline static llvm::Type * getLLVMTy(llvm::LLVMContext & ctxt)
 }
 
 template<typename Out>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), false);
 }
 
 template<typename Out, typename In1>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), llvm::ArrayRef<llvm::Type *>(getLLVMTy<In1>(ctxt)), false);
 }
 
 template<typename Out, typename In1, typename In2>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     llvm::Type * args[] = { getLLVMTy<In1>(ctxt), getLLVMTy<In2>(ctxt) };
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), args, false);
 }
 
 template<typename Out, typename In1, typename In2, typename In3>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     llvm::Type * args[] = { getLLVMTy<In1>(ctxt), getLLVMTy<In2>(ctxt), getLLVMTy<In3>(ctxt) };
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), llvm::ArrayRef<llvm::Type *>(args), false);
 }
 
 template<typename Out, typename In1, typename In2, typename In3, typename In4>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     llvm::Type * args[] = { getLLVMTy<In1>(ctxt), getLLVMTy<In2>(ctxt), getLLVMTy<In3>(ctxt), getLLVMTy<In4>(ctxt) };
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), llvm::ArrayRef<llvm::Type *>(args), false);
 }
 
 template<typename Out, typename In1, typename In2, typename In3, typename In4, typename In5>
-inline llvm::Type * getLLVMFuncTy(llvm::LLVMContext & ctxt)
+inline llvm::FunctionType * getLLVMFuncTy(llvm::LLVMContext & ctxt)
 {
     llvm::Type * args[] = { getLLVMTy<In1>(ctxt), getLLVMTy<In2>(ctxt), getLLVMTy<In3>(ctxt), getLLVMTy<In4>(ctxt), getLLVMTy<In5>(ctxt) };
     return llvm::FunctionType::get(getLLVMTy<Out>(ctxt), llvm::ArrayRef<llvm::Type *>(args), false);
@@ -343,13 +371,13 @@ inline llvm::Type * getLLVMPtrFuncTy(llvm::LLVMContext & ctxt)
 }
 
 template<typename T, typename U>
-static void putInContext_S(symbol::Context * ctxt, symbol::Variable * var, U x)
+inline static void putInContext_S(symbol::Context * ctxt, symbol::Variable * var, U x)
 {
     ctxt->put(var, new T(x));
 }
 
 template<typename T, typename U>
-static void putInContext_M(symbol::Context * ctxt, symbol::Variable * var, U * x, int r, int c)
+inline static void putInContext_M(symbol::Context * ctxt, symbol::Variable * var, U * x, int r, int c)
 {
     double * data;
     ctxt->put(var, new T(r, c, &data));
index ae68f7b..e5f7cd2 100644 (file)
@@ -122,10 +122,9 @@ template<> inline types::InternalType* add_M_M<types::Sparse, types::Double, typ
 //same type
 template<typename T, typename O> inline static void add(T* l, long long size, T* r, O* o)
 {
-    //std::cout << "out=" << (void*)o << ":::" << size << std::endl;
     for (int i = 0; i < size ; ++i)
     {
-        //o[i] = (O)l[i] + (O)r[i];
+        o[i] = (O)l[i] + (O)r[i];
     }
 }
 
diff --git a/scilab/modules/ast/src/cpp/jit/GlobalCFunctions.cpp b/scilab/modules/ast/src/cpp/jit/GlobalCFunctions.cpp
new file mode 100644 (file)
index 0000000..86056aa
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2014 - 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 "allexp.hxx"
+#include "allvar.hxx"
+
+#include "ScilabJITTraits.hxx"
+#include "types_addition.hxx"
+#include "types_substraction.hxx"
+#include "types_multiplication.hxx"
+
+extern "C"
+{
+    void putInContext_S_D_d(symbol::Context * ctxt, symbol::Variable * var, double x)
+    {
+        jit::putInContext_S<Double, double>(ctxt, var, x);
+    }
+
+    void putInContext_M_D_ds(symbol::Context * ctxt, symbol::Variable * var, double * x, int r, int c)
+    {
+        jit::putInContext_M<Double, double>(ctxt, var, x, r, c);
+    }
+
+    void add_M_M_d_d(double * l, long long size, double * r, double * o)
+    {
+        add<double, double>(l, size, r, o);
+    }
+
+    void sub_M_M_d_d(double * l, long long size, double * r, double * o)
+    {
+        sub<double, double>(l, size, r, o);
+    }
+
+    void dotmul_M_M_d_d(double * l, long long size, double * r, double * o)
+    {
+        dotmul<double, double>(l, size, r, o);
+    }
+}
index d558c71..a2e9648 100644 (file)
@@ -70,11 +70,14 @@ JITVisitor::JITVisitor(const analysis::AnalysisVisitor & _analysis) : ast::Const
 
 void JITVisitor::run()
 {
-    // on reinjecte les resultats ds l'environnement
+    // on reinjecte les resultats ds l'environnement a=1;jit("a=2");
     symbol::Context * ctxt = symbol::Context::getInstance();
     llvm::Value * llvmCtxt = getPointer(ctxt);
-    llvm::Value * toCall_S = getPointer(reinterpret_cast<void *>(&jit::putInContext_S<Double, double>), getLLVMPtrFuncTy<void, char *, char *, double>(context));
-    llvm::Value * toCall_M = getPointer(reinterpret_cast<void *>(&jit::putInContext_M<Double, double*>), getLLVMPtrFuncTy<void, char *, char *, double *, int, int>(context));
+    //llvm::Value * toCall_S = getPointer(reinterpret_cast<void *>(&jit::putInContext_S<Double, double>), getLLVMPtrFuncTy<void, char *, char *, double>(context));
+    llvm::Value * toCall_M = module.getOrInsertFunction("putInContext_M_D_ds", getLLVMFuncTy<void, char *, char *, double *, int , int>(context));
+    //llvm::Value * toCall_M = getPointer(reinterpret_cast<void *>(&jit::putInContext_M<Double, double*>), getLLVMPtrFuncTy<void, char *, char *, double *, int, int>(context));
+
+    llvm::Value * toCall_S = module.getOrInsertFunction("putInContext_S_D_d", getLLVMFuncTy<void, char *, char *, double>(context));
 
     for (JITSymbolMap::const_iterator i = symMap3.begin(), end = symMap3.end(); i != end; ++i)
     {
@@ -86,6 +89,7 @@ void JITVisitor::run()
         }
         else
         {
+            i->second.get()->load(*this)->dump();
             builder.CreateCall5(toCall_M, llvmCtxt, llvmVar, i->second.get()->load(*this), i->second.get()->loadR(*this), i->second.get()->loadC(*this));
         }
     }
@@ -361,44 +365,92 @@ void JITVisitor::visit(const ast::ForExp &e)
     {
         const ast::ListExp & list = static_cast<const ast::ListExp &>(init);
         const double * list_values = list.get_values();
-        llvm::Value * start, * step, * end;
+        llvm::Value * start = nullptr, * step, * end;
         bool use_int = false;
         bool use_uint = false;
+        bool inc = true;
+        bool known_step = false;
 
-        if (ISNAN(list_values[0]) || ISNAN(list_values[1]) || ISNAN(list_values[2]))
-        {
-            list.start_get().accept(*this);
-            start = result_get().get()->load(*this);
-
-            list.step_get().accept(*this);
-            step = result_get().get()->load(*this);
-
-            list.end_get().accept(*this);
-            end = result_get().get()->load(*this);
-        }
-        else
+        if (!ISNAN(list_values[0]) && !ISNAN(list_values[1]) && !ISNAN(list_values[2]))
         {
             const double tstart = std::trunc(list_values[0]);
             const double tstep = std::trunc(list_values[1]);
             const double tend = std::trunc(list_values[2]);
 
+            inc = list_values[1] >= 0;
+            known_step = true;
+
             if ((tstart == list_values[0]) && (tstep == list_values[1]))
             {
                 if (tstart >= 0 && tstep >= 0 && tstart <= list_values[2])
                 {
                     // we can use an unsigned int but take care to overflow...
-                    double k = std::floor(((double)std::numeric_limits<unsigned int>::max() - tstart) / tstep);
+                    double k = std::floor(((double)std::numeric_limits<uint64_t>::max() - tstart) / tstep);
                     if ((k * tstep + tstart) >= tend)
                     {
                         // no overflow
-                        start = getConstant((unsigned int)tstart);
-                        step = getConstant((unsigned int)tstep);
-                        end = getConstant((unsigned int)tend);
+                        start = getConstant((uint64_t)tstart);
+                        step = getConstant((uint64_t)tstep);
+                        end = getConstant((uint64_t)tend);
 
                         use_int = true;
                         use_uint = true;
                     }
                 }
+                else
+                {
+                    double k = std::floor(((double)(inc ? std::numeric_limits<int64_t>::max() : std::numeric_limits<int64_t>::min()) - tstart) / tstep);
+                    if ((inc && (k * tstep + tstart) >= tend) || (!inc && (k * tstep + tstart) <= tend))
+                    {
+                        // no overflow
+                        start = getConstant((int64_t)tstart);
+                        step = getConstant((int64_t)tstep);
+                        end = getConstant((int64_t)tend);
+
+                        use_int = true;
+                    }
+                }
+            }
+            else
+            {
+                start = getConstant(list_values[0]);
+                step = getConstant(list_values[1]);
+                end = getConstant(list_values[2]);
+            }
+        }
+
+        if (!start)
+        {
+            if (!ISNAN(list_values[0]))
+            {
+                start = getConstant(list_values[0]);
+            }
+            else
+            {
+                list.start_get().accept(*this);
+                start = result_get().get()->load(*this);
+            }
+
+            if (!ISNAN(list_values[1]))
+            {
+                step = getConstant(list_values[1]);
+                inc = list_values[1] >= 0;
+                known_step = true;
+            }
+            else
+            {
+                list.step_get().accept(*this);
+                step = result_get().get()->load(*this);
+            }
+
+            if (!ISNAN(list_values[2]))
+            {
+                end = getConstant(list_values[2]);
+            }
+            else
+            {
+                list.end_get().accept(*this);
+                end = result_get().get()->load(*this);
             }
         }
 
@@ -406,11 +458,28 @@ void JITVisitor::visit(const ast::ForExp &e)
         llvm::BasicBlock * BBAfter = llvm::BasicBlock::Create(context, "for_after", function);
 
         llvm::BasicBlock * cur_block = builder.GetInsertBlock();
-        llvm::Value * tmp = use_int ? (use_uint ? builder.CreateICmpULE(start, end) : builder.CreateICmpSLE(start, end)) : builder.CreateFCmpOLE(start, end);
+        llvm::Value * tmp;
+
+        if (known_step)
+        {
+            if (inc)
+            {
+                tmp = use_int ? (use_uint ? builder.CreateICmpULE(start, end) : builder.CreateICmpSLE(start, end)) : builder.CreateFCmpOLE(start, end);
+            }
+            else
+            {
+                tmp = use_int ? (use_uint ? builder.CreateICmpUGE(start, end) : builder.CreateICmpSGE(start, end)) : builder.CreateFCmpOGE(start, end);
+            }
+        }
+        else
+        {
+            //TODO: add something to handle this case
+        }
+
         builder.CreateCondBr(tmp, BBBody, BBAfter);
 
         builder.SetInsertPoint(BBBody);
-        llvm::PHINode * phi = use_int ? builder.CreatePHI(getLLVMTy<int>(context), 2) : builder.CreatePHI(getLLVMTy<double>(context), 2);
+        llvm::PHINode * phi = use_int ? builder.CreatePHI(getLLVMTy<int64_t>(context), 2) : builder.CreatePHI(getLLVMTy<double>(context), 2);
 
         JITSymbolMap::const_iterator i = symMap3.find(varName);
         tmp = use_int ? (use_uint ? builder.CreateUIToFP(phi, getLLVMTy<double>(context)) : builder.CreateSIToFP(phi, getLLVMTy<double>(context))) : phi;
@@ -424,13 +493,26 @@ void JITVisitor::visit(const ast::ForExp &e)
         tmp = use_int ? builder.CreateAdd(phi, step) : builder.CreateFAdd(phi, step);
         phi->addIncoming(tmp, builder.GetInsertBlock());
 
-        tmp = use_int ? (use_uint ? builder.CreateICmpULE(tmp, end) : builder.CreateICmpSLE(tmp, end)) : builder.CreateFCmpOLE(tmp, end);
+        if (known_step)
+        {
+            if (inc)
+            {
+                tmp = use_int ? (use_uint ? builder.CreateICmpULE(tmp, end) : builder.CreateICmpSLE(tmp, end)) : builder.CreateFCmpOLE(tmp, end);
+            }
+            else
+            {
+                tmp = use_int ? (use_uint ? builder.CreateICmpUGE(tmp, end) : builder.CreateICmpSGE(tmp, end)) : builder.CreateFCmpOGE(tmp, end);
+            }
+        }
+        else
+        {
+            //TODO: add something to handle this case
+        }
+
         builder.CreateCondBr(tmp, BBBody, BBAfter);
 
         builder.SetInsertPoint(BBAfter);
 
-        dump();
-
         //llvm::AllocaInst * cur = builder.CreateAlloca(getLLVMTy<double>(context));
         //llvm::StoreInst * cur_store = builder.CreateAlignedStore(phi, cur, sizeof(double));
 
index c4e6a9b..83bb6ca 100644 (file)
@@ -49,7 +49,8 @@ std::shared_ptr<JITVal> add_M_M(std::shared_ptr<JITVal> & L, std::shared_ptr<JIT
     llvm::Value * alloc = llvm::CallInst::CreateMalloc(cur_block, getLLVMTy<int>(context), getLLVMTy<double>(context), malloc_size);
     cur_block->getInstList().push_back(llvm::cast<llvm::Instruction>(alloc));
 
-    llvm::Value * toCall = visitor.getPointer(reinterpret_cast<void *>((void (*)(double *, long long, double *, double*))&::add<double, double>), getLLVMPtrFuncTy<void, double *, long long, double *, double *>(context));
+    llvm::Value * toCall = visitor.getModule().getOrInsertFunction("add_M_M_d_d", getLLVMFuncTy<void, double *, long long, double *, double *>(context));
+
 
     size = builder.CreateIntCast(size, getLLVMTy<long long>(context), false);
     builder.CreateCall4(toCall, L.get()->load(visitor), size, R.get()->load(visitor), alloc);
@@ -71,7 +72,7 @@ std::shared_ptr<JITVal> sub_M_M(std::shared_ptr<JITVal> & L, std::shared_ptr<JIT
     llvm::Value * alloc = llvm::CallInst::CreateMalloc(cur_block, getLLVMTy<int>(context), getLLVMTy<double>(context), malloc_size);
     cur_block->getInstList().push_back(llvm::cast<llvm::Instruction>(alloc));
 
-    llvm::Value * toCall = visitor.getPointer(reinterpret_cast<void *>((void (*)(double *, long long, double *, double*))&::sub<double, double>), getLLVMPtrFuncTy<void, double *, long long, double *, double *>(context));
+    llvm::Value * toCall = visitor.getModule().getOrInsertFunction("sub_M_M_d_d", getLLVMFuncTy<void, double *, long long, double *, double *>(context));
 
     size = builder.CreateIntCast(size, getLLVMTy<long long>(context), false);
     builder.CreateCall4(toCall, L.get()->load(visitor), size, R.get()->load(visitor), alloc);
@@ -90,7 +91,7 @@ std::shared_ptr<JITVal> dotmul_M_M(std::shared_ptr<JITVal> & L, std::shared_ptr<
     llvm::Value * alloc = llvm::CallInst::CreateMalloc(cur_block, getLLVMTy<int>(context), getLLVMTy<double>(context), malloc_size);
     cur_block->getInstList().push_back(llvm::cast<llvm::Instruction>(alloc));
 
-    llvm::Value * toCall = visitor.getPointer(reinterpret_cast<void *>((void (*)(double *, long long, double *, double*))&::dotmul<double, double>), getLLVMPtrFuncTy<void, double *, long long, double *, double *>(context));
+    llvm::Value * toCall = visitor.getModule().getOrInsertFunction("dotmul_M_M_d_d", getLLVMFuncTy<void, double *, long long, double *, double *>(context));
 
     size = builder.CreateIntCast(size, getLLVMTy<long long>(context), false);
     builder.CreateCall4(toCall, L.get()->load(visitor), size, R.get()->load(visitor), alloc);