JIT: improve forexp 93/17193/2
Calixte DENIZET [Thu, 10 Sep 2015 17:01:03 +0000 (19:01 +0200)]
Change-Id: Ifdb8eaa78ea872d13a873a1eb4500b496f1f229c

scilab/modules/ast/src/cpp/ast/debugvisitor.cpp
scilab/modules/ast/src/cpp/jit/JITForExp.cpp
scilab/modules/ast/src/cpp/jit/JITVisitor.cpp

index ed49e4a..74f0312 100644 (file)
@@ -56,7 +56,7 @@ void DebugVisitor::DEBUG(wstring str, const Exp &e)
     Location loc = e.getLocation();
     *ostr << L" @(" << loc.first_line << L"." << loc.first_column << L" -> ";
     *ostr << loc.last_line << L"." << loc.last_column << L")";
-    //*ostr << L" Deco(" << e.getDecorator() << L")" << endl;
+    *ostr << L" Deco(" << e.getDecorator() << L")" << endl;
 }
 
 
index 9c5d2f5..5737e00 100644 (file)
  *
  */
 
+#include <cstdlib>
+
 #include "JITScalars.hxx"
 #include "JITArrayofs.hxx"
 #include "JITVisitor.hxx"
 
 namespace jit
 {
-    void JITVisitor::visit(const ast::VarDec & e)
-    {
+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.
 
-    void JITVisitor::visit(const ast::ForExp & e)
+  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());
+    // TODO : handle for with an iterator
+    if (vd.getInit().isListExp())
     {
-       const ast::VarDec & vd = static_cast<const ast::VarDec &>(e.getVardec());
-       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);
-/*
-               llvm::Value * cmp_i1 = builder.CreateICmpSLT(start, end);
-               builder.CreateCondBr(cmp_i1, BBBody, BBAfter);
-
-               builder.SetInsertPoint(BBBody);
-               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);
-
-               if (builder.GetInsertBlock() != BBAfter)
-               {
-                   BBAfter->moveAfter(builder.GetInsertBlock());
-               }
-               
-               llvm::Value * ipstp_i64 = builder.CreateAdd(i, step);
-               i->addIncoming(ipstp_i64, builder.GetInsertBlock());
-               cmp_i1 = builder.CreateICmpSLT(ipstp_i64, end);
-               builder.CreateCondBr(cmp_i1, BBBody, BBAfter);
-               builder.SetInsertPoint(BBAfter);
-*/
-           }
-           
-       }
-
-       
-       // e.getBody().accept(*this);
-    }
+        const symbol::Symbol & symIterator = vd.getSymbol();
+        const ast::ListExp & le = static_cast<const ast::ListExp &>(vd.getInit());
+
+        if (le.getDecorator().getResult().getType().type != analysis::TIType::EMPTY)
+        {
+            llvm::Value * start = nullptr;
+            llvm::Value * step = nullptr;
+            llvm::Value * end = nullptr;
+            const ast::Exp & startE = le.getStart();
+            const ast::Exp & stepE = le.getStep();
+            const ast::Exp & endE = le.getEnd();
+            const analysis::TIType & startTy = startE.getDecorator().getResult().getType();
+            const analysis::TIType & stepTy = stepE.getDecorator().getResult().getType();
+            const analysis::TIType & endTy = endE.getDecorator().getResult().getType();
+            const bool startTyIsSigned = startTy.isintegral() && startTy.issigned();
+            const bool stepTyIsSigned = stepTy.isintegral() && stepTy.issigned();
+            const bool endTyIsSigned = endTy.isintegral() && endTy.issigned();
+            bool constantStart = false;
+            bool constantStep = false;
+            bool constantEnd = false;
+            bool signStep;
+            bool integralStep = false;
+            bool integerIterator = false;
+            int64_t step_i;
+            int64_t start_i;
+            int64_t end_i;
+            double step_d;
+            double start_d;
+            double end_d;
+
+            if (stepE.isDoubleExp())
+            {
+                // Step is constant
+                constantStep = true;
+                const ast::DoubleExp & stepDE = static_cast<const ast::DoubleExp &>(stepE);
+                step_d = stepDE.getValue();
+                signStep = step_d > 0;
+                if (!signStep)
+                {
+                    step_d = -step_d;
+                }
+                if (analysis::tools::asInteger(step_d, step_i))
+                {
+                    integralStep = true;
+                }
+            }
+            else
+            {
+                // Step is not constant
+                // Check if step is zero or not
+                const analysis::TIType & ty = stepE.getDecorator().getResult().getType();
+                if (ty.isintegral() || ty.isreal())
+                {
+                    stepE.accept(*this);
+                    step = getResult()->loadData(*this);
+                }
+                else
+                {
+                    // TODO: error
+                    return;
+                }
+            }
+
+            if (startE.isDoubleExp())
+            {
+                constantStart = true;
+                const ast::DoubleExp & startDE = static_cast<const ast::DoubleExp &>(startE);
+                start_d = startDE.getValue();
+                if (analysis::tools::asInteger(start_d, start_i))
+                {
+                    integerIterator = integralStep;
+                    if (integerIterator)
+                    {
+                        start = getConstant(start_i);
+                        step = getConstant(step_i);
+                    }
+                }
+                if (!start)
+                {
+                    start = getConstant(start_d);
+                    if (!step)
+                    {
+                        step = getConstant(step_d);
+                    }
+                }
+            }
+            else
+            {
+                startE.accept(*this);
+                start = getResult()->loadData(*this);
+                if (!step)
+                {
+                    step = getConstant(step_d);
+                }
+            }
+
+            if (endE.isDoubleExp())
+            {
+                constantEnd = true;
+                const ast::DoubleExp & endDE = static_cast<const ast::DoubleExp &>(endE);
+                end_d = endDE.getValue();
+                if (analysis::tools::asInteger(end_d, end_i))
+                {
+                    end = getConstant(end_i);
+                }
+                else
+                {
+                    end = getConstant(end_d);
+                }
+            }
+            else
+            {
+                endE.accept(*this);
+                end = getResult()->loadData(*this);
+            }
+
+            if (le.getDecorator().getResult().getRange().isValid())
+            {
+                integerIterator = true;
+            }
+
+            if (integerIterator)
+            {
+                start = Cast::cast<int64_t>(start, startTyIsSigned, *this);
+                step = Cast::cast<int64_t>(step, stepTyIsSigned, *this);
+                end = Cast::cast<int64_t>(end, endTyIsSigned, *this);
+                llvm::Value * one = getConstant<int64_t>(1);
+                if (constantStep)
+                {
+                    if (signStep)
+                    {
+                        end = builder.CreateAdd(end, one);
+                    }
+                    else
+                    {
+                        end = builder.CreateSub(end, one);
+                    }
+                }
+            }
+            else
+            {
+                start = Cast::cast<double>(start, startTyIsSigned, *this);
+                step = Cast::cast<double>(step, stepTyIsSigned, *this);
+                end = Cast::cast<double>(end, endTyIsSigned, *this);
+            }
+
+            // integers values: for i = start:step:end...
+            // is equivalent to for (int64_t i = start; i < end + 1; i += step)...
+
+            // flaoting values: for i = start:step:end...
+            // is equivalent to for (double i = start; i <= end; i += step)...
+
+            llvm::BasicBlock * cond = llvm::BasicBlock::Create(context, "for_cond", function);
+            llvm::BasicBlock * loop = llvm::BasicBlock::Create(context, "for_loop", function);
+            llvm::BasicBlock * after = llvm::BasicBlock::Create(context, "for_after", function);
+
+            // To know how to break or continue the loop
+            blocks.emplace(cond, after);
+
+            llvm::Value * sign_step = nullptr;
+            llvm::Value * zero_i64 = getConstant<int64_t>(0);
+            llvm::Value * zero_dbl = getConstant<double>(0);
+            llvm::Value * abs = llvm::Intrinsic::getDeclaration(&getModule(), llvm::Intrinsic::fabs, getTy<double>());
+            llvm::Value * abs_arg[1];
+            llvm::Value * cmp_i1 = nullptr;
+
+            if (!constantStep)
+            {
+                llvm::Value * cmp_zero;
+                if (integerIterator)
+                {
+                    cmp_zero = builder.CreateICmpEQ(step, zero_i64);
+                }
+                else
+                {
+                    cmp_zero = builder.CreateFCmpOEQ(step, zero_dbl);
+                }
+                llvm::BasicBlock * precond = llvm::BasicBlock::Create(context, "", function);
+                builder.CreateCondBr(cmp_zero, after, precond);
+                builder.SetInsertPoint(precond);
+            }
 
+            if (!integerIterator)
+            {
+                if (!constantStart)
+                {
+                    abs_arg[0] = start;
+                    llvm::CallInst * abs_start = builder.CreateCall(abs, abs_arg);
+                    abs_start->setTailCall(true);
+                    cmp_i1 = builder.CreateFCmpUEQ(abs_start, getConstant<double>(std::numeric_limits<double>::infinity()));
+                    llvm::BasicBlock * bb = llvm::BasicBlock::Create(context, "", function);
+                    builder.CreateCondBr(cmp_i1, after, bb);
+                    builder.SetInsertPoint(bb);
+                }
+
+                if (!constantEnd)
+                {
+                    abs_arg[0] = end;
+                    llvm::CallInst * abs_end = builder.CreateCall(abs, abs_arg);
+                    abs_end->setTailCall(true);
+                    cmp_i1 = builder.CreateFCmpUEQ(abs_end, getConstant<double>(std::numeric_limits<double>::infinity()));
+                    llvm::BasicBlock * bb = llvm::BasicBlock::Create(context, "", function);
+                    builder.CreateCondBr(cmp_i1, after, bb);
+                    builder.SetInsertPoint(bb);
+                }
+            }
+
+            if (integerIterator)
+            {
+                if (constantStep)
+                {
+                    if (signStep)
+                    {
+                        cmp_i1 = builder.CreateICmpSLT(start, end);
+                    }
+                    else
+                    {
+                        cmp_i1 = builder.CreateICmpSGT(start, end);
+                    }
+                }
+                else
+                {
+                    sign_step = builder.CreateICmpSGT(step, zero_i64);
+                    llvm::Value * cmp1 = builder.CreateICmpSLT(start, end);
+                    llvm::Value * cmp2 = builder.CreateICmpSGT(start, end);
+                    cmp_i1 = builder.CreateSelect(sign_step, cmp1, cmp2);
+                }
+            }
+            else
+            {
+                if (constantStep)
+                {
+                    if (signStep)
+                    {
+                        cmp_i1 = builder.CreateFCmpOLE(start, end);
+                    }
+                    else
+                    {
+                        cmp_i1 = builder.CreateFCmpOGE(start, end);
+                    }
+                }
+                else
+                {
+                    abs_arg[0] = step;
+                    llvm::CallInst * abs_step = builder.CreateCall(abs, abs_arg);
+                    abs_step->setTailCall(true);
+                    cmp_i1 = builder.CreateFCmpUEQ(abs_step, getConstant<double>(std::numeric_limits<double>::infinity()));
+                    llvm::BasicBlock * bb = llvm::BasicBlock::Create(context, "", function);
+                    builder.CreateCondBr(cmp_i1, after, bb);
+                    builder.SetInsertPoint(bb);
+                    sign_step = builder.CreateFCmpOGT(step, zero_dbl);
+                    llvm::Value * cmp1 = builder.CreateFCmpOLE(start, end);
+                    llvm::Value * cmp2 = builder.CreateFCmpOGE(start, end);
+                    cmp_i1 = builder.CreateSelect(sign_step, cmp1, cmp2);
+                }
+            }
+
+            builder.CreateCondBr(cmp_i1, loop, after);
+
+            llvm::BasicBlock * cur_block = builder.GetInsertBlock();
+
+            builder.SetInsertPoint(loop);
+            llvm::PHINode * i;
+            if (integerIterator)
+            {
+                i = builder.CreatePHI(getTy<int64_t>(), 2);
+            }
+            else
+            {
+                i = builder.CreatePHI(getTy<double>(), 2);
+            }
+
+            i->addIncoming(start, cur_block);
+            JITScilabPtr & it = variables.find(symIterator)->second;
+            //it->storeData(*this, i);
+
+            // Visit the loop body
+            e.getBody().accept(*this);
+
+            builder.CreateBr(cond);
+
+            builder.SetInsertPoint(cond);
+            llvm::Value * i_step;
+            if (integerIterator)
+            {
+                if (constantStep)
+                {
+                    if (signStep)
+                    {
+                        i_step = builder.CreateAdd(i, step);
+                        cmp_i1 = builder.CreateICmpSLT(i_step, end);
+                    }
+                    else
+                    {
+                        i_step = builder.CreateSub(i, step);
+                        cmp_i1 = builder.CreateICmpSGT(i_step, end);
+                    }
+                }
+                else
+                {
+                    i_step = builder.CreateAdd(i, step);
+                    llvm::Value * cmp1 = builder.CreateICmpSLT(i_step, end);
+                    llvm::Value * cmp2 = builder.CreateICmpSGT(i_step, end);
+                    cmp_i1 = builder.CreateSelect(sign_step, cmp1, cmp2);
+                }
+            }
+            else
+            {
+                if (constantStep)
+                {
+                    if (signStep)
+                    {
+                        i_step = builder.CreateFAdd(i, step);
+                        cmp_i1 = builder.CreateFCmpOLE(i_step, end);
+                    }
+                    else
+                    {
+                        i_step = builder.CreateFSub(i, step);
+                        cmp_i1 = builder.CreateFCmpOGE(i_step, end);
+                    }
+                }
+                else
+                {
+                    i_step = builder.CreateFAdd(i, step);
+                    llvm::Value * cmp1 = builder.CreateFCmpOLE(i_step, end);
+                    llvm::Value * cmp2 = builder.CreateFCmpOGE(i_step, end);
+                    cmp_i1 = builder.CreateSelect(sign_step, cmp1, cmp2);
+                }
+            }
+
+            i->addIncoming(i_step, cond);
+
+            builder.CreateCondBr(cmp_i1, loop, after);
+
+            builder.SetInsertPoint(after);
+        }
+    }
+}
 }
index a2f72dd..fae2bee 100644 (file)
 
 namespace jit
 {
-    const bool JITVisitor::__init__ = InitializeLLVM();
-
-    JITVisitor::JITVisitor(const analysis::AnalysisVisitor & _analysis) : ast::ConstVisitor(),
-                                                                          analysis(_analysis),
-                                                                          context(llvm::getGlobalContext()),
-                                                                          module(new llvm::Module("JIT", context)),
-                                                                         target(nullptr),
-                                                                          engine(InitializeEngine(module, &target)),
-                                                                          FPM(initFPM(module, engine, target)),
-                                                                          function(nullptr),
-                                                                          builder(context),
-                                                                          uintptrType(getPtrAsIntTy(*module, context)),
-                                                                          dblTy(llvm::Type::getDoubleTy(context)),
-                                                                          int1Ty(llvm::Type::getInt1Ty(context)),
-                                                                          int8Ty(llvm::Type::getInt8Ty(context)),
-                                                                          int16Ty(llvm::Type::getInt16Ty(context)),
-                                                                          int32Ty(llvm::Type::getInt32Ty(context)),
-                                                                          int64Ty(llvm::Type::getInt64Ty(context)),
-                                                                          voidTy(llvm::Type::getVoidTy(context)),
-                                                                          dblPtrTy(llvm::Type::getDoublePtrTy(context)),
-                                                                          int1PtrTy(llvm::Type::getInt1PtrTy(context)),
-                                                                          int8PtrTy(llvm::Type::getInt8PtrTy(context)),
-                                                                          int16PtrTy(llvm::Type::getInt16PtrTy(context)),
-                                                                          int32PtrTy(llvm::Type::getInt32PtrTy(context)),
-                                                                          int64PtrTy(llvm::Type::getInt64PtrTy(context)),
-                                                                          _result(nullptr),
-                                                                         cpx_rvalue(nullptr)
-    {
-        //std::wcerr << "Map size=" << MemoryManager::getMapSize() << std::endl;
-    }
+const bool JITVisitor::__init__ = InitializeLLVM();
+
+JITVisitor::JITVisitor(const analysis::AnalysisVisitor & _analysis) : ast::ConstVisitor(),
+    analysis(_analysis),
+    context(llvm::getGlobalContext()),
+    module(new llvm::Module("JIT", context)),
+    target(nullptr),
+    engine(InitializeEngine(module, &target)),
+    FPM(initFPM(module, engine, target)),
+    function(nullptr),
+    builder(context),
+    uintptrType(getPtrAsIntTy(*module, context)),
+    dblTy(llvm::Type::getDoubleTy(context)),
+    int1Ty(llvm::Type::getInt1Ty(context)),
+    int8Ty(llvm::Type::getInt8Ty(context)),
+    int16Ty(llvm::Type::getInt16Ty(context)),
+    int32Ty(llvm::Type::getInt32Ty(context)),
+    int64Ty(llvm::Type::getInt64Ty(context)),
+    voidTy(llvm::Type::getVoidTy(context)),
+    dblPtrTy(llvm::Type::getDoublePtrTy(context)),
+    int1PtrTy(llvm::Type::getInt1PtrTy(context)),
+    int8PtrTy(llvm::Type::getInt8PtrTy(context)),
+    int16PtrTy(llvm::Type::getInt16PtrTy(context)),
+    int32PtrTy(llvm::Type::getInt32PtrTy(context)),
+    int64PtrTy(llvm::Type::getInt64PtrTy(context)),
+    _result(nullptr),
+    cpx_rvalue(nullptr)
+{
+    //std::wcerr << "Map size=" << MemoryManager::getMapSize() << std::endl;
+}
 
-    JITVisitor::~JITVisitor()
-    {
-       delete engine;
-    }
+JITVisitor::~JITVisitor()
+{
+    delete engine;
+}
 
-    void JITVisitor::run()
-    {
+void JITVisitor::run()
+{
 
-    }
+}
 
-    void JITVisitor::dump() const
-    {
-        module->dump();
-        //function->dump();
-    }
+void JITVisitor::dump() const
+{
+    module->dump();
+    //function->dump();
+}
 
-    void JITVisitor::runOptimizationPasses()
-    {
+void JITVisitor::runOptimizationPasses()
+{
 #if TIME_LLVM == 1
-       std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
+    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
 #endif
-       for (llvm::Module::iterator it = module->begin(), end = module->end(); it != end; ++it)
-        {
-            FPM.run(*it);
-        }
-       
+    for (llvm::Module::iterator it = module->begin(), end = module->end(); it != end; ++it)
+    {
+        FPM.run(*it);
+    }
+
 #if TIME_LLVM == 1
-       std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
-       double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
-       std::wcerr << "Optimization time=" << duration << " s." << std::endl;
+    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
+    double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
+    std::wcerr << "Optimization time=" << duration << " s." << std::endl;
 #endif
-    }
+}
+
+void JITVisitor::compileModule()
+{
+    /*std::string error;
+    llvm::raw_fd_ostream stream("/tmp/scilab.s", error, llvm::sys::fs::OpenFlags::F_None);
+    llvm::formatted_raw_ostream frs(stream);
+    llvm::PassManager PM;
+    target->addPassesToEmitFile(PM, frs, llvm::TargetMachine::CGFT_AssemblyFile);
+    PM.run(*module);
+    frs.flush();
+    stream.close();*/
+
 
-    void JITVisitor::compileModule()
-    {
-       std::string error;
-       llvm::raw_fd_ostream stream("/tmp/scilab.s", error, llvm::sys::fs::OpenFlags::F_None);
-       llvm::formatted_raw_ostream frs(stream);
-       llvm::PassManager PM;
-       target->addPassesToEmitFile(PM, frs, llvm::TargetMachine::CGFT_AssemblyFile);
-       PM.run(*module);
-       frs.flush();
-       stream.close();
-
-       
 #if TIME_LLVM == 1
-       std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
+    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
 #endif
 
-       engine->finalizeObject();
-       
+    engine->finalizeObject();
+
 #if TIME_LLVM == 1
-       std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
-       double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
-       std::wcerr << "Compile time=" << duration << " s." << std::endl;
+    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
+    double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
+    std::wcerr << "Compile time=" << duration << " s." << std::endl;
 #endif
-    }
+}
 
-    JITScilabPtr & JITVisitor::getCpxRValue()
-    {
-       return cpx_rvalue;
-    }    
-    
-    llvm::Value * JITVisitor::getPtrFromIndex(const ast::CallExp & ce)
+JITScilabPtr & JITVisitor::getCpxRValue()
+{
+    return cpx_rvalue;
+}
+
+llvm::Value * JITVisitor::getPtrFromIndex(const ast::CallExp & ce)
+{
+    if (ce.getDecorator().getResult().getType().isscalar())
     {
-        if (ce.getDecorator().getResult().getType().isscalar())
-        {              
-            ce.getName().accept(*this);
-            JITScilabPtr mat = getResult();
-           ast::exps_t args = ce.getArgs();
-           const std::size_t size = args.size();
-           llvm::Value * index = nullptr;
-           if (size == 1)
-           {
-               const ast::Exp & first = *args.front();
-               first.accept(*this);
-               index = getResult()->loadData(*this);
-               if (!first.getDecorator().getResult().isAnInt())
-               {
-                   // argument is not an int64_t => cast
-                   index = Cast::cast<int64_t>(index, true, *this);
-               }
-               index = builder.CreateSub(index, getConstant<int64_t>(1));
-           }
-           else if (size == 2)
-           {
-               const ast::Exp & first = *args.front();
-               const ast::Exp & second = *args.back();
-               first.accept(*this);
-               llvm::Value * index_R = getResult()->loadData(*this);
-               second.accept(*this);
-               llvm::Value * index_C = getResult()->loadData(*this);
-               if (!first.getDecorator().getResult().isAnInt())
-               {
-                   // argument is not an int64_t => cast
-                   index_R = Cast::cast<int64_t>(index_R, true, *this);
-               }
-               if (!second.getDecorator().getResult().isAnInt())
-               {
-                   // argument is not an int64_t => cast
-                   index_C = Cast::cast<int64_t>(index_C, true, *this);
-               }
-               llvm::Value * one = getConstant<int64_t>(1);
-               index_R = builder.CreateSub(index_R, one);
-               index_C = builder.CreateSub(index_C, one);
-
-               // now compute the index
-               index = builder.CreateMul(index_C, mat->loadRows(*this));
-               index = builder.CreateAdd(index_R, index);
-           }
-           
-           if (index)
-           {
-               if (ce.getDecorator().safe)
-               {
-                   return builder.CreateGEP(mat->loadData(*this), index);
-               }
-               else
-               {
-                   llvm::Value * rc = builder.CreateMul(mat->loadRows(*this), mat->loadCols(*this));
-                   llvm::Value * check = builder.CreateICmpSLT(index, rc);
-                   // TODO: branch on error if check is false
-                   return builder.CreateGEP(mat->loadData(*this), index);
-               }
-           }
+        ce.getName().accept(*this);
+        JITScilabPtr mat = getResult();
+        ast::exps_t args = ce.getArgs();
+        const std::size_t size = args.size();
+        llvm::Value * index = nullptr;
+        if (size == 1)
+        {
+            const ast::Exp & first = *args.front();
+            first.accept(*this);
+            index = getResult()->loadData(*this);
+            if (!first.getDecorator().getResult().isAnInt())
+            {
+                // argument is not an int64_t => cast
+                index = Cast::cast<int64_t>(index, true, *this);
+            }
+            index = builder.CreateSub(index, getConstant<int64_t>(1));
         }
+        else if (size == 2)
+        {
+            const ast::Exp & first = *args.front();
+            const ast::Exp & second = *args.back();
+            first.accept(*this);
+            llvm::Value * index_R = getResult()->loadData(*this);
+            second.accept(*this);
+            llvm::Value * index_C = getResult()->loadData(*this);
+            if (!first.getDecorator().getResult().isAnInt())
+            {
+                // argument is not an int64_t => cast
+                index_R = Cast::cast<int64_t>(index_R, true, *this);
+            }
+            if (!second.getDecorator().getResult().isAnInt())
+            {
+                // argument is not an int64_t => cast
+                index_C = Cast::cast<int64_t>(index_C, true, *this);
+            }
+            llvm::Value * one = getConstant<int64_t>(1);
+            index_R = builder.CreateSub(index_R, one);
+            index_C = builder.CreateSub(index_C, one);
 
-       return nullptr;
-    }
+            // now compute the index
+            index = builder.CreateMul(index_C, mat->loadRows(*this));
+            index = builder.CreateAdd(index_R, index);
+        }
 
-    void JITVisitor::closeEntryBlock()
-    {
-       builder.SetInsertPoint(entryBlock);
-       CreateBr(mainBlock);
-    }
-    
-    void JITVisitor::CreateBr(llvm::BasicBlock * bb)
-    {
-       llvm::BasicBlock * cur_block = builder.GetInsertBlock();
-       if (cur_block->empty() || !llvm::isa<llvm::BranchInst>(cur_block->back()))
-       {
-           builder.CreateBr(bb);
-       }
+        if (index)
+        {
+            if (ce.getDecorator().safe)
+            {
+                return builder.CreateGEP(mat->loadData(*this), index);
+            }
+            else
+            {
+                llvm::Value * rc = builder.CreateMul(mat->loadRows(*this), mat->loadCols(*this));
+                llvm::Value * check = builder.CreateICmpSLT(index, rc);
+                // TODO: branch on error if check is false
+                return builder.CreateGEP(mat->loadData(*this), index);
+            }
+        }
     }
 
-    void JITVisitor::visit(const ast::SimpleVar & e)
+    return nullptr;
+}
+
+void JITVisitor::closeEntryBlock()
+{
+    builder.SetInsertPoint(entryBlock);
+    CreateBr(mainBlock);
+}
+
+void JITVisitor::CreateBr(llvm::BasicBlock * bb)
+{
+    llvm::BasicBlock * cur_block = builder.GetInsertBlock();
+    if (cur_block->empty() || !llvm::isa<llvm::BranchInst>(cur_block->back()))
     {
-        setResult(variables.find(e.getSymbol())->second);
+        builder.CreateBr(bb);
     }
+}
 
-    void JITVisitor::visit(const ast::DollarVar & e)
-    {
+void JITVisitor::visit(const ast::SimpleVar & e)
+{
+    setResult(variables.find(e.getSymbol())->second);
+}
 
-    }
+void JITVisitor::visit(const ast::DollarVar & e)
+{
 
-    void JITVisitor::visit(const ast::ColonVar & e)
-    {
+}
 
-    }
+void JITVisitor::visit(const ast::ColonVar & e)
+{
 
-    void JITVisitor::visit(const ast::ArrayListVar & e)
-    {
+}
 
-    }
+void JITVisitor::visit(const ast::ArrayListVar & e)
+{
+
+}
 
-    void JITVisitor::visit(const ast::DoubleExp & e)
+void JITVisitor::visit(const ast::DoubleExp & e)
+{
+    if (e.getDecorator().getResult().isAnInt())
     {
-       if (e.getDecorator().getResult().isAnInt())
-       {
-           setResult(JITScilabPtr(new JITScalInt64(*this, (int64_t)e.getValue(), false, "")));
-       }
-       else
-       {
-           if (types::Double * pDbl = static_cast<types::Double *>(e.getConstant()))
-           {
-               if (pDbl->isComplex())
-               {
-                   setResult(JITScilabPtr(new JITScalComplex(*this, std::complex<double>(pDbl->get(0), pDbl->getImg(0)), false, "")));
-               }
-               else
-               {
-                   setResult(JITScilabPtr(new JITScalDouble(*this, pDbl->get(0), false, "")));
-               }
-           }
-           else
-           {
-               setResult(JITScilabPtr(new JITScalDouble(*this, e.getValue(), false, "")));
-           }
-       }           
+        setResult(JITScilabPtr(new JITScalInt64(*this, (int64_t)e.getValue(), false, "")));
     }
-
-    void JITVisitor::visit(const ast::BoolExp & e)
+    else
     {
-
+        if (types::Double * pDbl = static_cast<types::Double *>(e.getConstant()))
+        {
+            if (pDbl->isComplex())
+            {
+                setResult(JITScilabPtr(new JITScalComplex(*this, std::complex<double>(pDbl->get(0), pDbl->getImg(0)), false, "")));
+            }
+            else
+            {
+                setResult(JITScilabPtr(new JITScalDouble(*this, pDbl->get(0), false, "")));
+            }
+        }
+        else
+        {
+            setResult(JITScilabPtr(new JITScalDouble(*this, e.getValue(), false, "")));
+        }
     }
+}
 
-    void JITVisitor::visit(const ast::StringExp & e)
-    {
+void JITVisitor::visit(const ast::BoolExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::NilExp & e)
-    {
+void JITVisitor::visit(const ast::StringExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::CellCallExp & e)
-    {
+void JITVisitor::visit(const ast::NilExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::AssignExp & e)
-    {
+void JITVisitor::visit(const ast::CellCallExp & e)
+{
+
+}
 
-        if (e.getLeftExp().isSimpleVar()) // A = ...
+void JITVisitor::visit(const ast::AssignExp & e)
+{
+
+    if (e.getLeftExp().isSimpleVar()) // A = ...
+    {
+        const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(e.getLeftExp()).getSymbol();
+        if (e.getRightExp().isSimpleVar())
         {
-            const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(e.getLeftExp()).getSymbol();
-            if (e.getRightExp().isSimpleVar())
+            // A = B so we just share the data
+            const symbol::Symbol & Rsym = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
+            JITScilabPtr & Lvalue = variables.find(Lsym)->second;
+            JITScilabPtr & Rvalue = variables.find(Rsym)->second;
+            Lvalue->storeRows(*this, Rvalue->loadRows(*this));
+            Lvalue->storeCols(*this, Rvalue->loadCols(*this));
+            Lvalue->storeData(*this, Rvalue->loadData(*this));
+            if (e.getRightExp().getDecorator().getResult().getType().type == analysis::TIType::COMPLEX)
             {
-                // A = B so we just share the data
-                const symbol::Symbol & Rsym = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
-                JITScilabPtr & Lvalue = variables.find(Lsym)->second;
-                JITScilabPtr & Rvalue = variables.find(Rsym)->second;
-               Lvalue->storeRows(*this, Rvalue->loadRows(*this));
-               Lvalue->storeCols(*this, Rvalue->loadCols(*this));
-                Lvalue->storeData(*this, Rvalue->loadData(*this));
-               if (e.getRightExp().getDecorator().getResult().getType().type == analysis::TIType::COMPLEX)
-               {
-                   Lvalue->storeImag(*this, Rvalue->loadImag(*this));
-               }
+                Lvalue->storeImag(*this, Rvalue->loadImag(*this));
             }
-            else
-            {
-               e.getRightExp().accept(*this);
-                // A = foo(...)...
-                if (!e.getRightExp().isCallExp())
-               {
-                   JITScilabPtr & Lvalue = variables.find(Lsym)->second;
-                   JITScilabPtr & Rvalue = getResult();
-                   Lvalue->storeRows(*this, Rvalue->loadRows(*this));
-                   Lvalue->storeCols(*this, Rvalue->loadCols(*this));
-                   Lvalue->storeData(*this, Rvalue->loadData(*this));
-                   if (e.getRightExp().getDecorator().getResult().getType().type == analysis::TIType::COMPLEX)
-                   {
-                       Lvalue->storeImag(*this, Rvalue->loadImag(*this));
-                   }
-               }
-           }
         }
-        else if (e.getLeftExp().isCallExp()) // A(12) = ...
+        else
         {
-            ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
-            if (ce.getName().isSimpleVar())
+            e.getRightExp().accept(*this);
+            // A = foo(...)...
+            if (!e.getRightExp().isCallExp())
             {
-                // We have an insertion
-                /**
-                 *  Several possibilities:
-                 *    i) A(I) = B(I): usually in Scilab that means:
-                 *       temp = B(I) and then A(I) = temp
-                 *       If we infered that the ext/ins is safe we can make a for loop:
-                 *          for k = 1:size(I,'*'), A(I(k)) = B(I(k)), end
-                 *    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();
-                if (e.getDecorator().safe && ce.getDecorator().getResult().getType().isscalar())
+                JITScilabPtr & Lvalue = variables.find(Lsym)->second;
+                JITScilabPtr & Rvalue = getResult();
+                Lvalue->storeRows(*this, Rvalue->loadRows(*this));
+                Lvalue->storeCols(*this, Rvalue->loadCols(*this));
+                Lvalue->storeData(*this, Rvalue->loadData(*this));
+                if (e.getRightExp().getDecorator().getResult().getType().type == analysis::TIType::COMPLEX)
                 {
-                   llvm::Value * ptr = getPtrFromIndex(ce);
-                   e.getRightExp().accept(*this);
-                   builder.CreateStore(getResult()->loadData(*this), ptr);
+                    Lvalue->storeImag(*this, Rvalue->loadImag(*this));
                 }
             }
         }
-        else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
+    }
+    else if (e.getLeftExp().isCallExp()) // A(12) = ...
+    {
+        ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
+        if (ce.getName().isSimpleVar())
         {
-            ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
-            if (e.getRightExp().isCallExp())
+            // We have an insertion
+            /**
+             *  Several possibilities:
+             *    i) A(I) = B(I): usually in Scilab that means:
+             *       temp = B(I) and then A(I) = temp
+             *       If we infered that the ext/ins is safe we can make a for loop:
+             *          for k = 1:size(I,'*'), A(I(k)) = B(I(k)), end
+             *    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();
+            if (e.getDecorator().safe && ce.getDecorator().getResult().getType().isscalar())
             {
+                llvm::Value * ptr = getPtrFromIndex(ce);
                 e.getRightExp().accept(*this);
+                builder.CreateStore(getResult()->loadData(*this), ptr);
             }
         }
     }
-
-    void JITVisitor::visit(const ast::TryCatchExp & e)
+    else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
     {
-
+        ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
+        if (e.getRightExp().isCallExp())
+        {
+            e.getRightExp().accept(*this);
+        }
     }
+}
 
-    void JITVisitor::visit(const ast::CaseExp & e)
-    {
-       // treated directly in SelectExp
-    }
+void JITVisitor::visit(const ast::TryCatchExp & e)
+{
 
-    void JITVisitor::visit(const ast::ReturnExp & e)
-    {
+}
 
-    }
+void JITVisitor::visit(const ast::CaseExp & e)
+{
+    // treated directly in SelectExp
+}
 
-    void JITVisitor::visit(const ast::FieldExp & e)
-    {
+void JITVisitor::visit(const ast::ReturnExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::TransposeExp & e)
-    {
+void JITVisitor::visit(const ast::FieldExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::MatrixExp & e)
-    {
+void JITVisitor::visit(const ast::TransposeExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::MatrixLineExp & e)
-    {
-       // treated in MatrixExp
-    }
+void JITVisitor::visit(const ast::MatrixExp & e)
+{
 
-    void JITVisitor::visit(const ast::CellExp & e)
-    {
+}
 
-    }
+void JITVisitor::visit(const ast::MatrixLineExp & e)
+{
+    // treated in MatrixExp
+}
+
+void JITVisitor::visit(const ast::CellExp & e)
+{
+
+}
 
-    void JITVisitor::visit(const ast::SeqExp & e)
+void JITVisitor::visit(const ast::SeqExp & e)
+{
+    for (ast::exps_t::const_iterator i = e.getExps().begin(), end = e.getExps().end(); i != end; ++i)
     {
-        for (ast::exps_t::const_iterator i = e.getExps().begin(), end = e.getExps().end(); i != end; ++i)
-        {
-            (*i)->accept(*this);
-        }
+        (*i)->accept(*this);
     }
+}
 
-    void JITVisitor::visit(const ast::ArrayListExp & e)
-    {
+void JITVisitor::visit(const ast::ArrayListExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::AssignListExp & e)
-    {
+void JITVisitor::visit(const ast::AssignListExp & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::FunctionDec & e)
-    {
+void JITVisitor::visit(const ast::FunctionDec & e)
+{
 
-    }
+}
 
-    void JITVisitor::visit(const ast::ListExp & e)
-    {
+void JITVisitor::visit(const ast::ListExp & e)
+{
 
-    }
+}
 
-    llvm::Type * JITVisitor::getType(const analysis::TIType::Type ty, const bool scalar)
+llvm::Type * JITVisitor::getType(const analysis::TIType::Type ty, const bool scalar)
+{
+    switch (ty)
     {
-        switch (ty)
-        {
         case analysis::TIType::DOUBLE:
             return scalar ? dblTy : dblPtrTy;
         case analysis::TIType::INT8:
@@ -425,23 +425,23 @@ namespace jit
         case analysis::TIType::INT64:
         case analysis::TIType::UINT64:
             return scalar ? int64Ty : int64PtrTy;
-       case analysis::TIType::BOOLEAN:
+        case analysis::TIType::BOOLEAN:
             return scalar ? int32Ty : int32PtrTy;
         default:
             return nullptr;
-        }
     }
+}
 
-    // TODO: virer ty comme args => useless
-    JITScilabPtr JITVisitor::getScalar(llvm::Value * const re, llvm::Value * const im, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
-    {
-       return std::shared_ptr<JITScilabVal>(new JITScalComplex(*this, re, im, alloc, name));
-    }
+// TODO: virer ty comme args => useless
+JITScilabPtr JITVisitor::getScalar(llvm::Value * const re, llvm::Value * const im, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+{
+    return std::shared_ptr<JITScilabVal>(new JITScalComplex(*this, re, im, alloc, name));
+}
 
-    JITScilabPtr JITVisitor::getScalar(llvm::Value * const value, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+JITScilabPtr JITVisitor::getScalar(llvm::Value * const value, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+{
+    switch (ty)
     {
-        switch (ty)
-        {
         case analysis::TIType::DOUBLE:
             return std::shared_ptr<JITScilabVal>(new JITScalDouble(*this, value, alloc, name));
         case analysis::TIType::INT8:
@@ -460,22 +460,22 @@ namespace jit
             return std::shared_ptr<JITScilabVal>(new JITScalUInt32(*this, value, alloc, name));
         case analysis::TIType::UINT64:
             return std::shared_ptr<JITScilabVal>(new JITScalUInt64(*this, value, alloc, name));
-       case analysis::TIType::BOOLEAN:
+        case analysis::TIType::BOOLEAN:
             return std::shared_ptr<JITScilabVal>(new JITScalBool(*this, value, alloc, name));
         default:
             return nullptr;
-        }
     }
+}
 
-    JITScilabPtr JITVisitor::getScalar(const analysis::TypeLocal & ty, const std::string & name)
-    {
-       return getScalar(ty.type, ty.isAnInt, name);
-    }
-    
-    JITScilabPtr JITVisitor::getScalar(const analysis::TIType::Type ty, const bool isAnInt, const std::string & name)
+JITScilabPtr JITVisitor::getScalar(const analysis::TypeLocal & ty, const std::string & name)
+{
+    return getScalar(ty.type, ty.isAnInt, name);
+}
+
+JITScilabPtr JITVisitor::getScalar(const analysis::TIType::Type ty, const bool isAnInt, const std::string & name)
+{
+    switch (ty)
     {
-        switch (ty)
-        {
         case analysis::TIType::DOUBLE:
             if (isAnInt)
             {
@@ -485,7 +485,7 @@ namespace jit
             {
                 return std::shared_ptr<JITScilabVal>(new JITScalDouble(*this, name));
             }
-       case analysis::TIType::COMPLEX:
+        case analysis::TIType::COMPLEX:
             return std::shared_ptr<JITScilabVal>(new JITScalComplex(*this, name));
         case analysis::TIType::INT8:
             return std::shared_ptr<JITScilabVal>(new JITScalInt8(*this, name));
@@ -503,22 +503,22 @@ namespace jit
             return std::shared_ptr<JITScilabVal>(new JITScalUInt32(*this, name));
         case analysis::TIType::UINT64:
             return std::shared_ptr<JITScilabVal>(new JITScalUInt64(*this, name));
-       case analysis::TIType::BOOLEAN:
+        case analysis::TIType::BOOLEAN:
             return std::shared_ptr<JITScilabVal>(new JITScalBool(*this, name));
         default:
             return nullptr;
-        }
     }
+}
 
-    /*JITScilabPtr JITVisitor::getMatrix(llvm::Value * const re, llvm::Value * const im, llvm::Value * const rows, llvm::Value * const cols, llvm::Value * const refCount, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
-    {
+/*JITScilabPtr JITVisitor::getMatrix(llvm::Value * const re, llvm::Value * const im, llvm::Value * const rows, llvm::Value * const cols, llvm::Value * const refCount, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+{
+
+}*/
 
-    }*/
-    
-    JITScilabPtr JITVisitor::getMatrix(llvm::Value * const value, llvm::Value * const rows, llvm::Value * const cols, llvm::Value * const refCount, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+JITScilabPtr JITVisitor::getMatrix(llvm::Value * const value, llvm::Value * const rows, llvm::Value * const cols, llvm::Value * const refCount, const analysis::TIType::Type ty, const bool alloc, const std::string & name)
+{
+    switch (ty)
     {
-        switch (ty)
-        {
         case analysis::TIType::DOUBLE:
             return std::shared_ptr<JITScilabVal>(new JITArrayofDouble(*this, value, rows, cols, refCount, alloc, name));
         case analysis::TIType::INT8:
@@ -537,17 +537,17 @@ namespace jit
             return std::shared_ptr<JITScilabVal>(new JITArrayofUInt32(*this, value, rows, cols, refCount, alloc, name));
         case analysis::TIType::UINT64:
             return std::shared_ptr<JITScilabVal>(new JITArrayofUInt64(*this, value, rows, cols, refCount, alloc, name));
-       case analysis::TIType::BOOLEAN:
+        case analysis::TIType::BOOLEAN:
             return std::shared_ptr<JITScilabVal>(new JITArrayofBool(*this, value, rows, cols, refCount, alloc, name));
         default:
             return nullptr;
-        }
     }
+}
 
-    JITScilabPtr JITVisitor::getMatrix(const analysis::TIType::Type ty, const std::string & name, const bool init)
+JITScilabPtr JITVisitor::getMatrix(const analysis::TIType::Type ty, const std::string & name, const bool init)
+{
+    switch (ty)
     {
-        switch (ty)
-        {
         case analysis::TIType::DOUBLE:
             return std::shared_ptr<JITScilabVal>(new JITArrayofDouble(*this, name, init));
         case analysis::TIType::INT8:
@@ -566,653 +566,655 @@ namespace jit
             return std::shared_ptr<JITScilabVal>(new JITArrayofUInt32(*this, name, init));
         case analysis::TIType::UINT64:
             return std::shared_ptr<JITScilabVal>(new JITArrayofUInt64(*this, name, init));
-       case analysis::TIType::BOOLEAN:
+        case analysis::TIType::BOOLEAN:
             return std::shared_ptr<JITScilabVal>(new JITArrayofBool(*this, name, init));
         default:
             return nullptr;
-        }
     }
+}
+
+JITScilabPtr JITVisitor::getMatrix(const analysis::TypeLocal & ty, const std::string & name, const bool init)
+{
+    return getMatrix(ty.type, name, init);
+}
 
-    JITScilabPtr JITVisitor::getMatrix(const analysis::TypeLocal & ty, const std::string & name, const bool init)
+void JITVisitor::action(analysis::FunctionBlock & fblock)
+{
+    variables.clear();
+    temps.clear();
+
+    //fblocks.emplace(&fblock);
+    std::string name(fblock.getName().begin(), fblock.getName().end());
+    const std::vector<std::pair<symbol::Symbol, analysis::TypeLocal>> ins = fblock.getTypesIn();
+    const std::vector<std::pair<symbol::Symbol, analysis::TypeLocal>> outs = fblock.getTypesOut();
+    mapNameFBlock.emplace(name, &fblock);
+    std::string _name(name);
+
+    // Firstly, we create the function signature
+    llvm::Type * retTy = voidTy;
+    std::vector<llvm::Type *> args;
+    args.reserve(4 * (ins.size() + outs.size()));
+    for (const auto & in : ins)
+    {
+        const analysis::TIType::Type ty = in.second.type;
+        const bool scalar = in.second.isScalar();
+        if (ty == analysis::TIType::COMPLEX)
+        {
+            llvm::Type * _ty = scalar ? dblTy : dblPtrTy;
+            args.emplace_back(_ty);
+            args.emplace_back(_ty);
+        }
+        else
+        {
+            args.emplace_back(getType(ty, scalar));
+        }
+        if (!scalar)
+        {
+            args.emplace_back(int64Ty); // for rows
+            args.emplace_back(int64Ty); // for cols
+            args.emplace_back(int64Ty); // for refcount
+        }
+        name += "_" + analysis::TIType::get_mangling(ty, scalar);
+    }
+    for (const auto & out : outs)
     {
-       return getMatrix(ty.type, name, init);
+        const analysis::TIType::Type ty = out.second.type;
+        const bool scalar = out.second.isScalar();
+
+        // Output arguments are passed by reference
+        if (ty == analysis::TIType::COMPLEX)
+        {
+            llvm::Type * _ty = scalar ? dblPtrTy : llvm::PointerType::getUnqual(dblPtrTy);
+            args.emplace_back(_ty);
+            args.emplace_back(_ty);
+        }
+        else
+        {
+            args.emplace_back(llvm::PointerType::getUnqual(getType(ty, scalar)));
+        }
+        if (!scalar)
+        {
+            args.emplace_back(int64PtrTy); // for rows
+            args.emplace_back(int64PtrTy); // for cols
+            args.emplace_back(int64PtrTy); // for refcount
+        }
     }
 
-    void JITVisitor::action(analysis::FunctionBlock & fblock)
+    llvm::FunctionType * ftype = llvm::FunctionType::get(retTy, llvm::ArrayRef<llvm::Type *>(args), /* isVarArgs */ false);
+    //function = llvm::cast<llvm::Function>(module.getOrInsertFunction("jit_" + name, ftype));
+    function = llvm::cast<llvm::Function>(module->getOrInsertFunction(_name, ftype));
+
+    entryBlock = llvm::BasicBlock::Create(context, "EntryBlock", function);
+    builder.SetInsertPoint(entryBlock);
+    mainBlock = llvm::BasicBlock::Create(context, "MainBlock", function);
+    returnBlock = llvm::BasicBlock::Create(context, "returnBlock", function);
+    //errorBlock = llvm::BasicBlock::Create(context, "errorBlock", function);
+
+    llvm::Function::arg_iterator ai = function->arg_begin();
+    for (const auto & in : ins)
     {
-        variables.clear();
-        temps.clear();
-
-        //fblocks.emplace(&fblock);
-        std::string name(fblock.getName().begin(), fblock.getName().end());
-        const std::vector<std::pair<symbol::Symbol, analysis::TypeLocal>> ins = fblock.getTypesIn();
-        const std::vector<std::pair<symbol::Symbol, analysis::TypeLocal>> outs = fblock.getTypesOut();
-       mapNameFBlock.emplace(name, &fblock);
-       std::string _name(name);
-
-        // Firstly, we create the function signature
-        llvm::Type * retTy = voidTy;
-        std::vector<llvm::Type *> args;
-        args.reserve(4 * (ins.size() + outs.size()));
-        for (const auto & in : ins)
+        const analysis::TIType::Type ty = in.second.type;
+        const bool scalar = in.second.isScalar();
+        const std::string name(in.first.getName().begin(), in.first.getName().end());
+        if (scalar)
         {
-            const analysis::TIType::Type ty = in.second.type;
-            const bool scalar = in.second.isScalar();
-           if (ty == analysis::TIType::COMPLEX)
-           {
-               llvm::Type * _ty = scalar ? dblTy : dblPtrTy;
-               args.emplace_back(_ty);
-               args.emplace_back(_ty);
-           }
-           else
-           {
-               args.emplace_back(getType(ty, scalar));
-           }
-            if (!scalar)
+            if (ty == analysis::TIType::COMPLEX)
             {
-                args.emplace_back(int64Ty); // for rows
-                args.emplace_back(int64Ty); // for cols
-                args.emplace_back(int64Ty); // for refcount
+                llvm::Value * re = ai++;
+                llvm::Value * im = ai++;
+
+                variables.emplace(in.first, getScalar(re, im, ty, true, name));
             }
-            name += "_" + analysis::TIType::get_mangling(ty, scalar);
-        }
-        for (const auto & out : outs)
-        {
-            const analysis::TIType::Type ty = out.second.type;
-            const bool scalar = out.second.isScalar();
-
-            // Output arguments are passed by reference
-           if (ty == analysis::TIType::COMPLEX)
-           {
-               llvm::Type * _ty = scalar ? dblPtrTy : llvm::PointerType::getUnqual(dblPtrTy);
-               args.emplace_back(_ty);
-               args.emplace_back(_ty);
-           }
-           else
-           {
-               args.emplace_back(llvm::PointerType::getUnqual(getType(ty, scalar)));
-           }
-            if (!scalar)
+            else
             {
-                args.emplace_back(int64PtrTy); // for rows
-                args.emplace_back(int64PtrTy); // for cols
-                args.emplace_back(int64PtrTy); // for refcount
+                variables.emplace(in.first, getScalar(ai++, ty, true, name));
             }
         }
+        else
+        {
+            llvm::Value * M = ai++;
+            llvm::Value * R = ai++;
+            llvm::Value * C = ai++;
+            llvm::Value * RC = ai++;
+            variables.emplace(in.first, getMatrix(M, R, C, RC, ty, true, name));
+        }
+    }
 
-        llvm::FunctionType * ftype = llvm::FunctionType::get(retTy, llvm::ArrayRef<llvm::Type *>(args), /* isVarArgs */ false);
-        //function = llvm::cast<llvm::Function>(module.getOrInsertFunction("jit_" + name, ftype));
-       function = llvm::cast<llvm::Function>(module->getOrInsertFunction(_name, ftype));
-
-        entryBlock = llvm::BasicBlock::Create(context, "EntryBlock", function);
-        builder.SetInsertPoint(entryBlock);
-       mainBlock = llvm::BasicBlock::Create(context, "MainBlock", function);
-       returnBlock = llvm::BasicBlock::Create(context, "returnBlock", function);
-       //errorBlock = llvm::BasicBlock::Create(context, "errorBlock", function);
-
-        llvm::Function::arg_iterator ai = function->arg_begin();
-        for (const auto & in : ins)
+    for (const auto & out : outs)
+    {
+        const analysis::TIType::Type ty = out.second.type;
+        const bool scalar = out.second.isScalar();
+        const std::string name(out.first.getName().begin(), out.first.getName().end());
+        if (scalar)
         {
-            const analysis::TIType::Type ty = in.second.type;
-            const bool scalar = in.second.isScalar();
-            const std::string name(in.first.getName().begin(), in.first.getName().end());
-            if (scalar)
+            JITScilabPtr & ptr = variables.emplace(out.first, getScalar(ty, /* isAnInt */ false, name)).first->second;
+
+            builder.SetInsertPoint(returnBlock);
+            if (ty == analysis::TIType::COMPLEX)
             {
-               if (ty == analysis::TIType::COMPLEX)
-               {
-                   llvm::Value * re = ai++;
-                   llvm::Value * im = ai++;
-                   
-                   variables.emplace(in.first, getScalar(re, im, ty, true, name));
-               }
-               else
-               {
-                   variables.emplace(in.first, getScalar(ai++, ty, true, name));
-               }
-           }
+                llvm::Value * re = ai++;
+                llvm::Value * im = ai++;
+                JITScalComplex * cpx_ptr = static_cast<JITScalComplex *>(ptr.get());
+                builder.CreateAlignedStore(cpx_ptr->loadReal(*this), re, sizeof(void *));
+                builder.CreateAlignedStore(cpx_ptr->loadImag(*this), im, sizeof(void *));
+            }
             else
             {
-                llvm::Value * M = ai++;
-                llvm::Value * R = ai++;
-                llvm::Value * C = ai++;
-                llvm::Value * RC = ai++;
-                variables.emplace(in.first, getMatrix(M, R, C, RC, ty, true, name));
+                builder.CreateAlignedStore(ptr->loadData(*this), ai++, sizeof(void *));
             }
+            builder.SetInsertPoint(entryBlock);
+        }
+        else
+        {
+            llvm::Value * M = ai++;
+            llvm::Value * R = ai++;
+            llvm::Value * C = ai++;
+            llvm::Value * RC = ai++;
+
+            JITScilabPtr & ptr = variables.emplace(out.first, getMatrix(ty, name)).first->second;
+
+            builder.SetInsertPoint(returnBlock);
+            builder.CreateAlignedStore(ptr->loadData(*this), M, sizeof(void *));
+            builder.CreateAlignedStore(ptr->loadRows(*this), R, sizeof(int64_t));
+            builder.CreateAlignedStore(ptr->loadCols(*this), C, sizeof(int64_t));
+            builder.SetInsertPoint(entryBlock);
+            //builder.CreateAlignedStore(ptr->loadRefCount(*this), RC, sizeof(int64_t));
+            //funOuts.emplace_back(getMatrix(M, R, C, RC, ty, false, ""));
         }
+    }
 
-        for (const auto & out : outs)
+    // Secondly, we need to create the variables used in the function.
+    const analysis::tools::SymbolMap<std::set<analysis::TypeLocal>> & locals = fblock.getTypesLocals();
+    for (const auto & local : locals)
+    {
+        const std::string name(local.first.getName().begin(), local.first.getName().end());
+        for (const auto & ty : local.second)
         {
-            const analysis::TIType::Type ty = out.second.type;
-            const bool scalar = out.second.isScalar();
-            const std::string name(out.first.getName().begin(), out.first.getName().end());
-            if (scalar)
+            if (ty.isScalar())
             {
-               JITScilabPtr & ptr = variables.emplace(out.first, getScalar(ty, /* isAnInt */ false, name)).first->second;
-
-               builder.SetInsertPoint(returnBlock);
-               if (ty == analysis::TIType::COMPLEX)
-               {
-                   llvm::Value * re = ai++;
-                   llvm::Value * im = ai++;
-                   JITScalComplex * cpx_ptr = static_cast<JITScalComplex *>(ptr.get());
-                   builder.CreateAlignedStore(cpx_ptr->loadReal(*this), re, sizeof(void *));
-                   builder.CreateAlignedStore(cpx_ptr->loadImag(*this), im, sizeof(void *));
-               }
-               else
-               {
-                   builder.CreateAlignedStore(ptr->loadData(*this), ai++, sizeof(void *));
-               }
-               builder.SetInsertPoint(entryBlock);
+                variables.emplace(local.first, getScalar(ty, name));
             }
             else
             {
-                llvm::Value * M = ai++;
-                llvm::Value * R = ai++;
-                llvm::Value * C = ai++;
-                llvm::Value * RC = ai++;
-
-               JITScilabPtr & ptr = variables.emplace(out.first, getMatrix(ty, name)).first->second;
-                               
-               builder.SetInsertPoint(returnBlock);
-               builder.CreateAlignedStore(ptr->loadData(*this), M, sizeof(void *));
-               builder.CreateAlignedStore(ptr->loadRows(*this), R, sizeof(int64_t));
-               builder.CreateAlignedStore(ptr->loadCols(*this), C, sizeof(int64_t));
-               builder.SetInsertPoint(entryBlock);
-               //builder.CreateAlignedStore(ptr->loadRefCount(*this), RC, sizeof(int64_t));
-                //funOuts.emplace_back(getMatrix(M, R, C, RC, ty, false, ""));
+                variables.emplace(local.first, getMatrix(ty, name));
             }
         }
+    }
 
-        // Secondly, we need to create the variables used in the function.
-       const analysis::tools::SymbolMap<std::set<analysis::TypeLocal>> & locals = fblock.getTypesLocals();
-        for (const auto & local : locals)
+    // Thirdly, we need to create the temporaries.
+    int total = 0;
+    const std::map<analysis::TypeLocal, std::stack<int>> & temporaries = fblock.getTemp();
+    for (const auto & p : temporaries)
+    {
+        total += p.second.size();
+    }
+    if (total > 0)
+    {
+        temps.resize(total);
+        unsigned int id = 0;
+        for (const auto & p : temporaries)
         {
-            const std::string name(local.first.getName().begin(), local.first.getName().end());
-            for (const auto & ty : local.second)
+            const analysis::TypeLocal & ty = p.first;
+            stack<int> stack(p.second);
+            while (!stack.empty())
             {
+                const std::string name = std::to_string(id++) + "_tmp";
                 if (ty.isScalar())
                 {
-                    variables.emplace(local.first, getScalar(ty, name));
+                    temps[stack.top()] = getScalar(ty, name);
                 }
                 else
                 {
-                    variables.emplace(local.first, getMatrix(ty, name));
+                    temps[stack.top()] = getMatrix(ty, name, true);
                 }
+                stack.pop();
             }
         }
+    }
 
-        // Thirdly, we need to create the temporaries.
-        int total = 0;
-        const std::map<analysis::TypeLocal, std::stack<int>> & temporaries = fblock.getTemp();
-        for (const auto & p : temporaries)
-        {
-            total += p.second.size();
-        }
-        if (total > 0)
+    cpx_rvalue.reset(new JITScalComplex(*this, "0_cpx_rvalue"));
+
+    //function->dump();
+
+    builder.SetInsertPoint(mainBlock);
+
+    fblock.getExp()->accept(*this);
+    //function->dump();
+    CreateBr(returnBlock);
+
+    builder.SetInsertPoint(returnBlock);
+    builder.CreateRetVoid();
+
+    //function->dump();
+
+
+    //module.dump();
+}
+
+void JITVisitor::makeCall(const std::wstring & name, const std::vector<types::InternalType *> & in, std::vector<types::InternalType *> & out)
+{
+    std::vector<llvm::Value *> args;
+    std::string _name(name.begin(), name.end());
+
+    for (auto pIT : in)
+    {
+        if (pIT->isGenericType())
         {
-            temps.resize(total);
-            unsigned int id = 0;
-            for (const auto & p : temporaries)
+            types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
+            if (pGT->isScalar())
             {
-                const analysis::TypeLocal & ty = p.first;
-                stack<int> stack(p.second);
-                while (!stack.empty())
+                switch (pGT->getType())
                 {
-                    const std::string name = std::to_string(id++) + "_tmp";
-                   if (ty.isScalar())
+                    case types::InternalType::ScilabInt8:
+                    {
+                        const int8_t x = static_cast<types::Int8 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt8:
+                    {
+                        const uint8_t x = static_cast<types::UInt8 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabInt16:
+                    {
+                        const int16_t x = static_cast<types::Int16 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt16:
+                    {
+                        const uint16_t x = static_cast<types::UInt16 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabInt32:
+                    {
+                        const int32_t x = static_cast<types::Int32 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt32:
                     {
-                        temps[stack.top()] = getScalar(ty, name);
+                        const uint32_t x = static_cast<types::UInt32 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
                     }
-                    else
+                    case types::InternalType::ScilabInt64:
                     {
-                        temps[stack.top()] = getMatrix(ty, name, true);
+                        const int64_t x = static_cast<types::Int64 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
                     }
-                    stack.pop();
+                    case types::InternalType::ScilabUInt64:
+                    {
+                        const uint64_t x = static_cast<types::UInt64 *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    case types::InternalType::ScilabDouble:
+                        if (pGT->isComplex())
+                        {
+                            const double re = static_cast<types::Double *>(pGT)->getReal()[0];
+                            const double im = static_cast<types::Double *>(pGT)->getImg()[0];
+                            args.emplace_back(getValue(re));
+                            args.emplace_back(getValue(im));
+                            //args.emplace_back(getValue(std::complex<double>(re, im)));
+                        }
+                        else
+                        {
+                            const double x = static_cast<types::Double *>(pGT)->get(0);
+                            args.emplace_back(getValue(x));
+                        }
+                        break;
+                    case types::InternalType::ScilabBool:
+                    {
+                        const int32_t x = static_cast<types::Bool *>(pGT)->get(0);
+                        args.emplace_back(getValue(x));
+                        break;
+                    }
+                    default:
+                        break;
                 }
             }
+            else
+            {
+                switch (pGT->getType())
+                {
+                    case types::InternalType::ScilabInt8:
+                    {
+                        makeArg<int8_t, types::Int8>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt8:
+                    {
+                        makeArg<uint8_t, types::UInt8>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabInt16:
+                    {
+                        makeArg<int16_t, types::Int16>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt16:
+                    {
+                        makeArg<uint16_t, types::UInt16>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabInt32:
+                    {
+                        makeArg<int32_t, types::Int32>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt32:
+                    {
+                        makeArg<uint32_t, types::UInt32>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabInt64:
+                    {
+                        makeArg<int64_t, types::Int64>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabUInt64:
+                    {
+                        makeArg<uint64_t, types::UInt64>(args, pGT);
+                        break;
+                    }
+                    case types::InternalType::ScilabDouble:
+                        if (pGT->isComplex())
+                        {
+                        }
+                        else
+                        {
+                            makeArg<double, types::Double>(args, pGT);
+                        }
+                        break;
+                    case types::InternalType::ScilabBool:
+                    {
+                        makeArg<int32_t, types::Bool>(args, pGT);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    // now we put the output
+    const std::vector<analysis::TIType> outs = mapNameFBlock.find(_name)->second->getOuts().tuple.types;
+    const analysis::TIType & ty = outs.front();
+    std::vector<OutContainer> llvmOuts;
+    llvmOuts.reserve(out.size());
+    llvmOuts.emplace_back(ty.type);
+
+    if (ty.isscalar())
+    {
+        switch (ty.type)
+        {
+            case analysis::TIType::DOUBLE:
+            {
+                args.emplace_back(getValue(&llvmOuts.back().data.dbl));
+                llvmOuts.back().rows = 1;
+                llvmOuts.back().cols = 1;
+                break;
+            }
+            case analysis::TIType::COMPLEX:
+            {
+                args.emplace_back(getValue(&llvmOuts.back().data.cpx[0]));
+                args.emplace_back(getValue(&llvmOuts.back().data.cpx[1]));
+                llvmOuts.back().rows = 1;
+                llvmOuts.back().cols = 1;
+                break;
+            }
+            case analysis::TIType::BOOLEAN:
+            {
+                args.emplace_back(getValue(&llvmOuts.back().data.boolean));
+                llvmOuts.back().rows = 1;
+                llvmOuts.back().cols = 1;
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    else
+    {
+        switch (ty.type)
+        {
+            case analysis::TIType::DOUBLE:
+            {
+                args.emplace_back(getValue(reinterpret_cast<double **>(&llvmOuts.back().data.ptr)));
+                args.emplace_back(getValue(&llvmOuts.back().rows));
+                args.emplace_back(getValue(&llvmOuts.back().cols));
+                args.emplace_back(getValue(&llvmOuts.back().refcount));
+                break;
+
+                /*types::Double * pDbl = new types::Double();
+                double ** x = &pDbl->m_pRealData;
+                args.emplace_back(getValue(x));
+                int32_t * r = &pDbl->m_iRows;
+                args.emplace_back(getValue(r));
+                int32_t * c = &pDbl->m_iCols;
+                args.emplace_back(getValue(c));
+                int32_t * refc = &pDbl->m_iRef;
+                args.emplace_back(getValue(refc));
+                out.push_back(pDbl);*/
+            }
+            default:
+                break;
         }
+    }
 
-       cpx_rvalue.reset(new JITScalComplex(*this, "0_cpx_rvalue"));
+    llvm::Type * voidTy = getTy<void>();
+    llvm::Function * toCall = module->getFunction(_name);
+    llvm::Function * function = llvm::cast<llvm::Function>(module->getOrInsertFunction("main", voidTy, nullptr));
+    llvm::BasicBlock * BB = llvm::BasicBlock::Create(context, "EntryBlock", function);
+    builder.SetInsertPoint(BB);
+    builder.CreateCall(toCall, llvm::ArrayRef<llvm::Value *>(args));
+    builder.CreateRetVoid();
 
-       //function->dump();
-       
-       builder.SetInsertPoint(mainBlock);
-        
-        fblock.getExp()->accept(*this);
-       //function->dump();
-       CreateBr(returnBlock);
+    std::chrono::steady_clock::time_point start;
+    std::chrono::steady_clock::time_point end;
 
-       builder.SetInsertPoint(returnBlock);
-        builder.CreateRetVoid();
+    closeEntryBlock();
 
-        //function->dump();
+    module->dump();
 
+    runOptimizationPasses();
 
-        //module.dump();
-    }
+    module->dump();
+
+    compileModule();
 
-    void JITVisitor::makeCall(const std::wstring & name, const std::vector<types::InternalType *> & in, std::vector<types::InternalType *> & out)
+    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();
+    double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
+    std::wcerr << "Exec time=" << duration << " s." << std::endl;
+
+    types::InternalType * pIT = nullptr;
+    if (ty.isscalar())
+    {
+        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)
+        {
+            pIT = new types::Double(llvmOuts.back().data.dbl);
+        }
+        else if (ty.type == analysis::TIType::BOOLEAN)
+        {
+            pIT = new types::Bool(llvmOuts.back().data.boolean);
+        }
+    }
+    else
     {
-       std::vector<llvm::Value *> args;
-       std::string _name(name.begin(), name.end());
-       
-       for (auto pIT : in)
-       {
-           if (pIT->isGenericType())
-           {
-               types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
-               if (pGT->isScalar())
-               {
-                   switch (pGT->getType())
-                   {
-                   case types::InternalType::ScilabInt8:
-                   {
-                       const int8_t x = static_cast<types::Int8 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt8:
-                   {
-                       const uint8_t x = static_cast<types::UInt8 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabInt16:
-                   {
-                       const int16_t x = static_cast<types::Int16 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt16:
-                   {
-                       const uint16_t x = static_cast<types::UInt16 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabInt32:
-                   {
-                       const int32_t x = static_cast<types::Int32 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt32:
-                   {
-                       const uint32_t x = static_cast<types::UInt32 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabInt64:
-                   {
-                       const int64_t x = static_cast<types::Int64 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt64:
-                   {
-                       const uint64_t x = static_cast<types::UInt64 *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   case types::InternalType::ScilabDouble:
-                       if (pGT->isComplex())
-                       {
-                           const double re = static_cast<types::Double *>(pGT)->getReal()[0];
-                           const double im = static_cast<types::Double *>(pGT)->getImg()[0];
-                           args.emplace_back(getValue(re));
-                           args.emplace_back(getValue(im));
-                           //args.emplace_back(getValue(std::complex<double>(re, im)));
-                       }
-                       else
-                       {
-                           const double x = static_cast<types::Double *>(pGT)->get(0);
-                           args.emplace_back(getValue(x));
-                       }
-                       break;
-                   case types::InternalType::ScilabBool:
-                   {
-                       const int32_t x = static_cast<types::Bool *>(pGT)->get(0);
-                       args.emplace_back(getValue(x));
-                       break;
-                   }
-                   default:
-                       break;
-                   }
-               }
-               else
-               {
-                   switch (pGT->getType())
-                   {
-                   case types::InternalType::ScilabInt8:
-                   {
-                       makeArg<int8_t, types::Int8>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt8:
-                   {
-                       makeArg<uint8_t, types::UInt8>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabInt16:
-                   {
-                       makeArg<int16_t, types::Int16>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt16:
-                   {
-                       makeArg<uint16_t, types::UInt16>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabInt32:
-                   {
-                       makeArg<int32_t, types::Int32>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt32:
-                   {
-                       makeArg<uint32_t, types::UInt32>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabInt64:
-                   {
-                       makeArg<int64_t, types::Int64>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabUInt64:
-                   {
-                       makeArg<uint64_t, types::UInt64>(args, pGT);
-                       break;
-                   }
-                   case types::InternalType::ScilabDouble:
-                       if (pGT->isComplex())
-                       {
-                       }
-                       else
-                       {
-                           makeArg<double, types::Double>(args, pGT);
-                       }
-                       break;
-                   case types::InternalType::ScilabBool:
-                   {
-                       makeArg<int32_t, types::Bool>(args, pGT);
-                       break;
-                   }
-                   default:
-                       break;
-                   }
-               }
-           }
-       }
-
-       // now we put the output
-       const std::vector<analysis::TIType> outs = mapNameFBlock.find(_name)->second->getOuts().tuple.types;
-       const analysis::TIType & ty = outs.front();
-       std::vector<OutContainer> llvmOuts;
-       llvmOuts.reserve(out.size());
-       llvmOuts.emplace_back(ty.type);
-       
-       if (ty.isscalar())
-       {
-           switch (ty.type)
-           {
-           case analysis::TIType::DOUBLE:
-           {
-               args.emplace_back(getValue(&llvmOuts.back().data.dbl));
-               llvmOuts.back().rows = 1;
-               llvmOuts.back().cols = 1;
-               break;
-           }
-           case analysis::TIType::COMPLEX:
-           {
-               args.emplace_back(getValue(&llvmOuts.back().data.cpx[0]));
-               args.emplace_back(getValue(&llvmOuts.back().data.cpx[1]));
-               llvmOuts.back().rows = 1;
-               llvmOuts.back().cols = 1;
-               break;
-           }
-           case analysis::TIType::BOOLEAN:
-           {
-               args.emplace_back(getValue(&llvmOuts.back().data.boolean));
-               llvmOuts.back().rows = 1;
-               llvmOuts.back().cols = 1;
-               break;
-           }
-           default:
-               break;
-           }
-       }
-       else
-       {
-           switch (ty.type)
-           {
-           case analysis::TIType::DOUBLE:
-           {
-               args.emplace_back(getValue(reinterpret_cast<double **>(&llvmOuts.back().data.ptr)));
-               args.emplace_back(getValue(&llvmOuts.back().rows));
-               args.emplace_back(getValue(&llvmOuts.back().cols));
-               args.emplace_back(getValue(&llvmOuts.back().refcount));
-               break;
-               
-               /*types::Double * pDbl = new types::Double();
-               double ** x = &pDbl->m_pRealData;
-               args.emplace_back(getValue(x));
-               int32_t * r = &pDbl->m_iRows;
-               args.emplace_back(getValue(r));
-               int32_t * c = &pDbl->m_iCols;
-               args.emplace_back(getValue(c));
-               int32_t * refc = &pDbl->m_iRef; 
-               args.emplace_back(getValue(refc));
-               out.push_back(pDbl);*/
-           }
-           default:
-               break;
-           }
-       }
-
-       llvm::Type * voidTy = getTy<void>();
-       llvm::Function * toCall = module->getFunction(_name);
-       llvm::Function * function = llvm::cast<llvm::Function>(module->getOrInsertFunction("main", voidTy, nullptr));
-       llvm::BasicBlock * BB = llvm::BasicBlock::Create(context, "EntryBlock", function);
-        builder.SetInsertPoint(BB);
-       builder.CreateCall(toCall, llvm::ArrayRef<llvm::Value *>(args));
-       builder.CreateRetVoid();
-       
-       module->dump();
-
-       std::chrono::steady_clock::time_point start;
-        std::chrono::steady_clock::time_point end;
-
-       closeEntryBlock();
-       runOptimizationPasses();        
-       
-        module->dump();
-
-       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();
-       double duration = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() * 1e-9;
-       std::wcerr << "Exec time=" << duration << " s." << std::endl;
-
-       types::InternalType * pIT = nullptr;
-       if (ty.isscalar())
-       {
-           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)
-           {
-               pIT = new types::Double(llvmOuts.back().data.dbl);
-           }
-           else if (ty.type == analysis::TIType::BOOLEAN)
-           {
-               pIT = new types::Bool(llvmOuts.back().data.boolean);
-           }
-       }
-       else
-       {
-           pIT = new types::Double(llvmOuts.back().rows, llvmOuts.back().cols, reinterpret_cast<double *>(llvmOuts.back().data.ptr));
-       }
-
-       out.emplace_back(pIT);  
+        pIT = new types::Double(llvmOuts.back().rows, llvmOuts.back().cols, reinterpret_cast<double *>(llvmOuts.back().data.ptr));
     }
 
-    llvm::FunctionType * JITVisitor::getFunctionType(const analysis::TIType & out, const std::vector<const analysis::TIType *> & types)
+    out.emplace_back(pIT);
+}
+
+llvm::FunctionType * JITVisitor::getFunctionType(const analysis::TIType & out, const std::vector<const analysis::TIType *> & types)
+{
+    llvm::Type * out_ty;
+    std::vector<llvm::Type *> args;
+    if (out.type == analysis::TIType::COMPLEX)
     {
-       llvm::Type * out_ty;
-       std::vector<llvm::Type *> args;
-       if (out.type == analysis::TIType::COMPLEX)
-       {
-           out_ty = getTy<void>();
-       }
-       else
-       {
-           out_ty = getTy(out);
-       }
-       for (const auto type : types)
-       {
-           if (type->isscalar())
-           {
-               if (type->type == analysis::TIType::COMPLEX)
-               {
-                   args.emplace_back(getTy<double>());
-                   args.emplace_back(getTy<double>());
-               }
-               else
-               {
-                   args.emplace_back(getTy(*type));
-               }
-           }
-           else
-           {
-               if (type->type == analysis::TIType::COMPLEX)
-               {
-                   args.emplace_back(getTy<double *>());
-                   args.emplace_back(getTy<double *>());
-               }
-               else
-               {
-                   args.emplace_back(getTy(*type, 1));
-               }
-               args.emplace_back(getTy<int64_t>());
-               args.emplace_back(getTy<int64_t>());
-           }
-       }
-       if (out.type == analysis::TIType::COMPLEX)
-       {
-           if (out.isscalar())
-           {
-               args.emplace_back(getTy<double *>());
-               args.emplace_back(getTy<double *>());
-           }
-           else
-           {
-               args.emplace_back(getTy<double **>());
-               args.emplace_back(getTy<double **>());
-               args.emplace_back(getTy<int64_t *>());
-               args.emplace_back(getTy<int64_t *>());
-           }
-       }
-
-       return llvm::FunctionType::get(out_ty, llvm::ArrayRef<llvm::Type *>(args), false);
+        out_ty = getTy<void>();
     }
-    
-    llvm::Type * JITVisitor::getPtrAsIntTy(llvm::Module & module, llvm::LLVMContext & ctxt)
+    else
     {
-#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR == 4
-        return module.getPointerSize() == llvm::Module::Pointer32 ? llvm::Type::getInt32Ty(ctxt) : llvm::Type::getInt64Ty(ctxt);
-#else
-        return module.getDataLayout()->getPointerSize() == 32 ? llvm::Type::getInt32Ty(ctxt) : llvm::Type::getInt64Ty(ctxt);
-#endif
+        out_ty = getTy(out);
     }
-
-    bool JITVisitor::InitializeLLVM()
+    for (const auto type : types)
     {
-        llvm::InitializeNativeTarget();
-        llvm::InitializeNativeTargetAsmPrinter();
-        llvm::InitializeNativeTargetAsmParser();
-
-        return true;
+        if (type->isscalar())
+        {
+            if (type->type == analysis::TIType::COMPLEX)
+            {
+                args.emplace_back(getTy<double>());
+                args.emplace_back(getTy<double>());
+            }
+            else
+            {
+                args.emplace_back(getTy(*type));
+            }
+        }
+        else
+        {
+            if (type->type == analysis::TIType::COMPLEX)
+            {
+                args.emplace_back(getTy<double *>());
+                args.emplace_back(getTy<double *>());
+            }
+            else
+            {
+                args.emplace_back(getTy(*type, 1));
+            }
+            args.emplace_back(getTy<int64_t>());
+            args.emplace_back(getTy<int64_t>());
+        }
     }
-
-    llvm::ExecutionEngine * JITVisitor::InitializeEngine(llvm::Module * module, llvm::TargetMachine ** target)
+    if (out.type == analysis::TIType::COMPLEX)
     {
-        std::string err;
-        llvm::TargetOptions opt;
-       opt.NoFramePointerElim = true;
-       llvm::EngineBuilder & eb = llvm::EngineBuilder(module).setErrorStr(&err).setUseMCJIT(true).setMCJITMemoryManager(new MemoryManager()).setRelocationModel(llvm::Reloc::PIC_/*DynamicNoPIC*//*Static*/).setCodeModel(llvm::CodeModel::Small).setTargetOptions(opt);
-       // TODO: when reloc model is Static there is a problem with address of global variables (used with dgemm_)
-       
-       *target = eb.selectTarget();
-       llvm::ExecutionEngine * engine = eb.create(*target);
-       engine->RegisterJITEventListener(new ScilabJITEventListener());
-
-       module->setDataLayout(engine->getDataLayout()->getStringRepresentation());
-       module->setTargetTriple((*target)->getTargetTriple().str());
-
-       return engine;
+        if (out.isscalar())
+        {
+            args.emplace_back(getTy<double *>());
+            args.emplace_back(getTy<double *>());
+        }
+        else
+        {
+            args.emplace_back(getTy<double **>());
+            args.emplace_back(getTy<double **>());
+            args.emplace_back(getTy<int64_t *>());
+            args.emplace_back(getTy<int64_t *>());
+        }
     }
 
-    llvm::FunctionPassManager JITVisitor::initFPM(llvm::Module * module, llvm::ExecutionEngine * engine, llvm::TargetMachine * target)
-    {
-        llvm::FunctionPassManager FPM(module);
+    return llvm::FunctionType::get(out_ty, llvm::ArrayRef<llvm::Type *>(args), false);
+}
 
+llvm::Type * JITVisitor::getPtrAsIntTy(llvm::Module & module, llvm::LLVMContext & ctxt)
+{
 #if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR == 4
-        FPM.add(new llvm::DataLayout(*engine->getDataLayout()));
+    return module.getPointerSize() == llvm::Module::Pointer32 ? llvm::Type::getInt32Ty(ctxt) : llvm::Type::getInt64Ty(ctxt);
 #else
-        FPM.add(new llvm::DataLayoutPass(*engine->getDataLayout()));
+    return module.getDataLayout()->getPointerSize() == 32 ? llvm::Type::getInt32Ty(ctxt) : llvm::Type::getInt64Ty(ctxt);
 #endif
+}
+
+bool JITVisitor::InitializeLLVM()
+{
+    llvm::InitializeNativeTarget();
+    llvm::InitializeNativeTargetAsmPrinter();
+    llvm::InitializeNativeTargetAsmParser();
 
-       target->addAnalysisPasses(FPM);
-       
-       // TODO: mettre les bonnes passes la ou il faut
+    return true;
+}
 
-       FPM.add(llvm::createBasicAliasAnalysisPass());
-        FPM.add(llvm::createTypeBasedAliasAnalysisPass());
-        FPM.add(llvm::createCFGSimplificationPass());
-       FPM.add(llvm::createAggressiveDCEPass());
-               
-        FPM.add(llvm::createPromoteMemoryToRegisterPass()); // remove useless alloca
-        FPM.add(llvm::createInstructionCombiningPass()); // clean
-        //FPM.add(llvm::createScalarReplAggregatesPass());
-        //FPM.add(llvm::createInstructionCombiningPass());
-        FPM.add(llvm::createJumpThreadingPass()); // thread jumps.
-        FPM.add(llvm::createInstructionCombiningPass()); // clean
-        FPM.add(llvm::createReassociatePass()); // use associativity to simplify
-        FPM.add(llvm::createEarlyCSEPass()); // common sub-expression elimination
-        FPM.add(llvm::createLoopIdiomPass()); // replace certains for-loop by memset/memcpy
-        FPM.add(llvm::createLoopRotatePass()); // ??
-        FPM.add(llvm::createLICMPass()); // Loop Invariant Code Motion
-        FPM.add(llvm::createLoopUnswitchPass()); // For-If are permuted
-        FPM.add(llvm::createInstructionCombiningPass()); // clean
-        FPM.add(llvm::createIndVarSimplifyPass()); // Transform induction var in loops into something like (i = 0; i != A; ++i)
-        FPM.add(llvm::createLoopDeletionPass()); // remove dead loops
-        //FPM.add(llvm::createLoopStrengthReducePass());
-        //FPM.add(llvm::createLoopUnrollPass(-1, -1, -1 /* allows partial unrolling (1 for unrolling) */, -1)); // unroll small loops
-       FPM.add(llvm::createBBVectorizePass()); // vectorize loops
-       FPM.add(llvm::createInstructionCombiningPass());
-       FPM.add(llvm::createGVNPass());
-       FPM.add(llvm::createLoopUnrollPass());
-       FPM.add(llvm::createAggressiveDCEPass());
-       
-       FPM.add(llvm::createLoopVectorizePass()); // vectorize loops
-        FPM.add(llvm::createInstructionCombiningPass()); //clean
-       FPM.add(llvm::createSLPVectorizerPass());
-        FPM.add(llvm::createGVNPass()); // global value numbering
-        FPM.add(llvm::createSCCPPass()); // Sparse Conditional Constant Propagation
-        FPM.add(llvm::createSinkingPass());
-        FPM.add(llvm::createInstructionSimplifierPass());
-        FPM.add(llvm::createInstructionCombiningPass());
-        FPM.add(llvm::createDeadInstEliminationPass());
-        FPM.add(llvm::createDeadStoreEliminationPass());
-        FPM.add(llvm::createAggressiveDCEPass());
+llvm::ExecutionEngine * JITVisitor::InitializeEngine(llvm::Module * module, llvm::TargetMachine ** target)
+{
+    std::string err;
+    llvm::TargetOptions opt;
+    opt.NoFramePointerElim = true;
+    llvm::EngineBuilder & eb = llvm::EngineBuilder(module).setErrorStr(&err).setUseMCJIT(true).setMCJITMemoryManager(new MemoryManager()).setRelocationModel(llvm::Reloc::PIC_/*DynamicNoPIC*//*Static*/).setCodeModel(llvm::CodeModel::Small).setTargetOptions(opt);
+    // TODO: when reloc model is Static there is a problem with address of global variables (used with dgemm_)
 
-        FPM.doInitialization();
+    *target = eb.selectTarget();
+    llvm::ExecutionEngine * engine = eb.create(*target);
+    engine->RegisterJITEventListener(new ScilabJITEventListener());
 
-       /*
+    module->setDataLayout(engine->getDataLayout()->getStringRepresentation());
+    module->setTargetTriple((*target)->getTargetTriple().str());
+
+    return engine;
+}
+
+llvm::FunctionPassManager JITVisitor::initFPM(llvm::Module * module, llvm::ExecutionEngine * engine, llvm::TargetMachine * target)
+{
+    llvm::FunctionPassManager FPM(module);
+
+#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR == 4
+    FPM.add(new llvm::DataLayout(*engine->getDataLayout()));
+#else
+    FPM.add(new llvm::DataLayoutPass(*engine->getDataLayout()));
+#endif
+
+    target->addAnalysisPasses(FPM);
+
+    // TODO: mettre les bonnes passes la ou il faut
+
+    FPM.add(llvm::createBasicAliasAnalysisPass());
+    FPM.add(llvm::createTypeBasedAliasAnalysisPass());
+    FPM.add(llvm::createCFGSimplificationPass());
+    FPM.add(llvm::createAggressiveDCEPass());
+
+    FPM.add(llvm::createPromoteMemoryToRegisterPass()); // remove useless alloca
+    FPM.add(llvm::createInstructionCombiningPass()); // clean
+    //FPM.add(llvm::createScalarReplAggregatesPass());
+    //FPM.add(llvm::createInstructionCombiningPass());
+    FPM.add(llvm::createJumpThreadingPass()); // thread jumps.
+    FPM.add(llvm::createInstructionCombiningPass()); // clean
+    FPM.add(llvm::createReassociatePass()); // use associativity to simplify
+    FPM.add(llvm::createEarlyCSEPass()); // common sub-expression elimination
+    FPM.add(llvm::createLoopIdiomPass()); // replace certains for-loop by memset/memcpy
+    FPM.add(llvm::createLoopRotatePass()); // ??
+    FPM.add(llvm::createLICMPass()); // Loop Invariant Code Motion
+    FPM.add(llvm::createLoopUnswitchPass()); // For-If are permuted
+    FPM.add(llvm::createInstructionCombiningPass()); // clean
+    FPM.add(llvm::createIndVarSimplifyPass()); // Transform induction var in loops into something like (i = 0; i != A; ++i)
+    FPM.add(llvm::createLoopDeletionPass()); // remove dead loops
+    //FPM.add(llvm::createLoopStrengthReducePass());
+    //FPM.add(llvm::createLoopUnrollPass(-1, -1, -1 /* allows partial unrolling (1 for unrolling) */, -1)); // unroll small loops
+    FPM.add(llvm::createBBVectorizePass()); // vectorize loops
+    FPM.add(llvm::createInstructionCombiningPass());
+    FPM.add(llvm::createGVNPass());
+    FPM.add(llvm::createLoopUnrollPass());
+    FPM.add(llvm::createAggressiveDCEPass());
+
+    FPM.add(llvm::createLoopVectorizePass()); // vectorize loops
+    FPM.add(llvm::createInstructionCombiningPass()); //clean
+    FPM.add(llvm::createSLPVectorizerPass());
+    FPM.add(llvm::createGVNPass()); // global value numbering
+    FPM.add(llvm::createSCCPPass()); // Sparse Conditional Constant Propagation
+    FPM.add(llvm::createSinkingPass());
+    FPM.add(llvm::createInstructionSimplifierPass());
+    FPM.add(llvm::createInstructionCombiningPass());
+    FPM.add(llvm::createDeadInstEliminationPass());
+    FPM.add(llvm::createDeadStoreEliminationPass());
+    FPM.add(llvm::createAggressiveDCEPass());
+
+    FPM.doInitialization();
+
+    /*
         // createBasicAliasAnalysisPass - This pass implements the stateless alias
         // analysis.
         FPM.add(llvm::createBasicAliasAnalysisPass());
@@ -1258,6 +1260,6 @@ namespace jit
 
         FPM.doInitialization();*/
 
-        return FPM;
-    }
+    return FPM;
+}
 }