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