Analysis: fix few bugs 43/16743/3
Calixte DENIZET [Mon, 29 Jun 2015 14:16:30 +0000 (16:16 +0200)]
Change-Id: I2115cbdbb356e28fd1e8c68f120272eb90afb6f1

53 files changed:
scilab/modules/ast/Makefile.am
scilab/modules/ast/Makefile.in
scilab/modules/ast/ast.vcxproj
scilab/modules/ast/ast.vcxproj.filters
scilab/modules/ast/includes/analysis/AnalysisVisitor.hxx
scilab/modules/ast/includes/analysis/Decorator.hxx
scilab/modules/ast/includes/analysis/FBlockEmittedListener.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/ForList.hxx
scilab/modules/ast/includes/analysis/Result.hxx
scilab/modules/ast/includes/analysis/TIType.hxx
scilab/modules/ast/includes/analysis/Temporary.hxx [deleted file]
scilab/modules/ast/includes/analysis/call/Call.hxx [moved from scilab/modules/ast/includes/analysis/Call.hxx with 99% similarity]
scilab/modules/ast/includes/analysis/call/SizeCall.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/data/Block.hxx
scilab/modules/ast/includes/analysis/data/DataManager.hxx
scilab/modules/ast/includes/analysis/data/FunctionBlock.hxx
scilab/modules/ast/includes/analysis/data/MacroDef.hxx
scilab/modules/ast/includes/analysis/data/TemporaryManager.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/data/TypeLocal.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/gvn/GVN.hxx
scilab/modules/ast/includes/analysis/gvn/InferenceConstraint.hxx
scilab/modules/ast/includes/analysis/gvn/MultivariateMonomial.hxx
scilab/modules/ast/includes/analysis/gvn/MultivariatePolynomial.hxx
scilab/modules/ast/includes/analysis/gvn/OpValue.hxx
scilab/modules/ast/includes/analysis/gvn/SymbolicDimension.hxx
scilab/modules/ast/includes/analysis/gvn/SymbolicRange.hxx
scilab/modules/ast/includes/analysis/gvn/TestGVNVisitor.hxx
scilab/modules/ast/includes/analysis/gvn/VarExp.hxx
scilab/modules/ast/includes/analysis/tools.hxx
scilab/modules/ast/includes/ast/debugvisitor.hxx
scilab/modules/ast/src/cpp/analysis/AnalysisVisitor.cpp
scilab/modules/ast/src/cpp/analysis/ArgnAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/Block.cpp
scilab/modules/ast/src/cpp/analysis/CompleteMacroSignature.cpp
scilab/modules/ast/src/cpp/analysis/ConstantValue.cpp
scilab/modules/ast/src/cpp/analysis/DiagAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/FunctionBlock.cpp
scilab/modules/ast/src/cpp/analysis/IndexAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/MacroDef.cpp
scilab/modules/ast/src/cpp/analysis/MatrixAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/OperGVNValues.cpp
scilab/modules/ast/src/cpp/analysis/OperSymbolicRange.cpp
scilab/modules/ast/src/cpp/analysis/PolymorphicMacroCache.cpp
scilab/modules/ast/src/cpp/analysis/SizeAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/SymbolicList.cpp
scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitIfExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitListExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitOpExp.cpp
scilab/modules/ast/src/cpp/ast/debugvisitor.cpp
scilab/modules/ast/tests/unit_tests/gvn.dia.ref
scilab/modules/ast/tests/unit_tests/gvn.tst
scilab/modules/functions/sci_gateway/cpp/sci_testGVN.cpp

index 7dce2c2..a18e4e9 100644 (file)
@@ -205,7 +205,7 @@ libsciast_scilab_la_includedir=$(pkgincludedir)
 libsciast_scilab_la_include_HEADERS = \
 includes/analysis/AnalysisVisitor.hxx \
 includes/analysis/checkers/Checkers.hxx \
-includes/analysis/Call.hxx \
+includes/analysis/call/Call.hxx \
 includes/analysis/ConstantValue.hxx \
 includes/analysis/Decorator.hxx \
 includes/analysis/ForList.hxx \
index 420dfa7..480fec3 100644 (file)
@@ -922,7 +922,7 @@ libsciast_scilab_la_includedir = $(pkgincludedir)
 libsciast_scilab_la_include_HEADERS = \
 includes/analysis/AnalysisVisitor.hxx \
 includes/analysis/checkers/Checkers.hxx \
-includes/analysis/Call.hxx \
+includes/analysis/call/Call.hxx \
 includes/analysis/ConstantValue.hxx \
 includes/analysis/Decorator.hxx \
 includes/analysis/ForList.hxx \
index 518194f..3f4a776 100644 (file)
@@ -279,6 +279,8 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\analysis\analyzers\TypeAnalyzer.hxx" />
     <ClInclude Include="includes\analysis\analyzers\TypeofAnalyzer.hxx" />
     <ClInclude Include="includes\analysis\Call.hxx" />
+    <ClInclude Include="includes\analysis\call\Call.hxx" />
+    <ClInclude Include="includes\analysis\call\SizeCall.hxx" />
     <ClInclude Include="includes\analysis\checkers\Checkers.hxx" />
     <ClInclude Include="includes\analysis\checkers\check_abs.hxx" />
     <ClInclude Include="includes\analysis\checkers\check_acos.hxx" />
@@ -376,10 +378,13 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\analysis\data\MacroInfo.hxx" />
     <ClInclude Include="includes\analysis\data\MacroSignature.hxx" />
     <ClInclude Include="includes\analysis\data\PolymorphicMacroCache.hxx" />
+    <ClInclude Include="includes\analysis\data\TemporaryManager.hxx" />
     <ClInclude Include="includes\analysis\data\TITypeSignatureTuple.hxx" />
     <ClInclude Include="includes\analysis\data\TITypeTuple.hxx" />
+    <ClInclude Include="includes\analysis\data\TypeLocal.hxx" />
     <ClInclude Include="includes\analysis\data\XBlock.hxx" />
     <ClInclude Include="includes\analysis\Decorator.hxx" />
+    <ClInclude Include="includes\analysis\FBlockEmittedListener.hxx" />
     <ClInclude Include="includes\analysis\ForList.hxx" />
     <ClInclude Include="includes\analysis\gvn\ConstraintManager.hxx" />
     <ClInclude Include="includes\analysis\gvn\GVN.hxx" />
@@ -397,7 +402,6 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\analysis\positivity\PositivityVisitor.hxx" />
     <ClInclude Include="includes\analysis\Result.hxx" />
     <ClInclude Include="includes\analysis\SymInfo.hxx" />
-    <ClInclude Include="includes\analysis\Temporary.hxx" />
     <ClInclude Include="includes\analysis\TIType.hxx" />
     <ClInclude Include="includes\analysis\tools.hxx" />
     <ClInclude Include="includes\ast\debugvisitor.hxx" />
index 5528151..d918bc1 100644 (file)
@@ -78,6 +78,9 @@
     <Filter Include="Header Files\analysis\positivity">
       <UniqueIdentifier>{8ed80f73-101f-4424-9cc3-dbd6293d0e05}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Header Files\analysis\call">
+      <UniqueIdentifier>{397aa440-f3cd-4be7-8f51-a9144b196a9d}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <None Include="core_Import.def">
     <ClInclude Include="includes\analysis\SymInfo.hxx">
       <Filter>Header Files\analysis</Filter>
     </ClInclude>
-    <ClInclude Include="includes\analysis\Temporary.hxx">
-      <Filter>Header Files\analysis</Filter>
-    </ClInclude>
     <ClInclude Include="includes\analysis\TIType.hxx">
       <Filter>Header Files\analysis</Filter>
     </ClInclude>
     <ClInclude Include="includes\analysis\positivity\PositivityVisitor.hxx">
       <Filter>Header Files\analysis\positivity</Filter>
     </ClInclude>
+    <ClInclude Include="includes\analysis\FBlockEmittedListener.hxx">
+      <Filter>Header Files\analysis</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\analysis\call\Call.hxx">
+      <Filter>Header Files\analysis\call</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\analysis\call\SizeCall.hxx">
+      <Filter>Header Files\analysis\call</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\analysis\data\TemporaryManager.hxx">
+      <Filter>Header Files\analysis\data</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\analysis\data\TypeLocal.hxx">
+      <Filter>Header Files\analysis\data</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\cpp\ast\debugvisitor.cpp">
index 68a4ee0..a822a3f 100644 (file)
 #include "ForList.hxx"
 #include "Result.hxx"
 #include "SymInfo.hxx"
-#include "Temporary.hxx"
 #include "TIType.hxx"
 #include "ConstantVisitor.hxx"
 #include "gvn/SymbolicList.hxx"
-
+#include "FBlockEmittedListener.hxx"
 #include "data/DataManager.hxx"
 #include "data/PolymorphicMacroCache.hxx"
 #include "gvn/ConstraintManager.hxx"
@@ -58,7 +57,6 @@ private:
 
     MapSymInfo symsinfo;
     Result _result;
-    Temporary temp;
     Calls allCalls;
     DataManager dm;
     PolymorphicMacroCache pmc;
@@ -68,6 +66,7 @@ private:
     ast::PrintVisitor pv;
     std::vector<Result> multipleLHS;
     logging::Logger logger;
+    std::vector<FBlockEmittedListener *> fblockListeners;
 
     static MapSymCall symscall;
     static MapSymCall initCalls();
@@ -128,6 +127,11 @@ public:
         return pv;
     }
 
+    inline ast::DebugVisitor & getDV()
+    {
+        return dv;
+    }
+
     inline ast::ExecVisitor & getExec()
     {
         return cv.getExec();
@@ -167,16 +171,6 @@ public:
         return _result;
     }
 
-    inline const Temporary & getTemp() const
-    {
-        return temp;
-    }
-
-    inline Temporary & getTemp()
-    {
-        return temp;
-    }
-
     inline const Calls & getCalls() const
     {
         return allCalls;
@@ -199,43 +193,20 @@ public:
         }
     }
 
-    template<typename T>
-    inline void visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, T && args)
+    inline void registerFBlockEmittedListener(FBlockEmittedListener * listener)
     {
-        std::vector<Result> resargs;
-        std::vector<TIType> vargs;
-        vargs.reserve(args.size());
-        resargs.reserve(args.size());
-
-        for (typename T::const_iterator i = args.begin(), end = args.end(); i != end; ++i)
-        {
-            (*i)->accept(*this);
-            resargs.push_back(getResult());
-            vargs.push_back(getResult().getType());
-        }
+       if (listener)
+       {
+           fblockListeners.push_back(listener);
+       }
+    }
 
-        const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
-        int tempId = -1;
-        if (lhs > 1)
-        {
-            std::vector<TIType> types = dm.call(*this, lhs, sym, vargs, &e);
-            multipleLHS.clear();
-            multipleLHS.reserve(types.size());
-            for (const auto & type : types)
-            {
-                multipleLHS.emplace_back(type);
-            }
-        }
-        else
-        {
-            std::vector<TIType> out = dm.call(*this, lhs, sym, vargs, &e);
-            if (lhs == 1)
-            {
-                e.getDecorator().res = Result(out[0], tempId);
-                e.getDecorator().setCall(name, vargs);
-                setResult(e.getDecorator().res);
-            }
-        }
+    inline void emitFunctionBlock(FunctionBlock & fblock)
+    {
+       for (auto listener : fblockListeners)
+       {
+           listener->action(fblock);
+       }
     }
 
     inline Info & getSymInfo(const symbol::Symbol & sym)
@@ -262,9 +233,49 @@ private:
         }
     }
 
+    template<TIType (F)(GVN &, const TIType &, const TIType &)>
+       inline TIType checkEWBinOp(TIType & LT, TIType & RT, const Result & LR, const Result & RR, bool & safe, int & tempId)
+    {
+       TIType resT = F(getGVN(), LT, RT);
+       if (resT.hasInvalidDims())
+       {
+           const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
+           
+           if (ret)
+           {
+               resT = F(getGVN(), LT, RT);
+               safe = true;
+           }
+           else
+           {
+               resT = resT.asUnknownMatrix();
+           }
+       }
+       else
+       {
+           safe = true;
+       }
+       
+       tempId = getTmpIdForEWOp(resT, LR, RR);
+       
+       if (resT.isscalar())
+       {
+       }
+
+       return resT;
+    }
+
+    
     bool operGVNValues(ast::OpExp & oe);
     bool operSymbolicRange(ast::OpExp & oe);
 
+    // get temp id for an element-wise operation
+    // A + (B + 1) => B+1 is a temp, A is not and we can reuse the temp to put the result of A + (B+1)
+    int getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR);
+    void visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, const ast::exps_t & args);
+
+    
+
     void visit(ast::SelectExp & e);
     void visit(ast::ListExp & e);
     void visit(ast::MatrixExp & e);
@@ -364,8 +375,8 @@ private:
         // TODO: e.getName() is not always a simple var: foo(a)(b)
         if (e.getName().isSimpleVar())
         {
-            ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getName());
-            symbol::Symbol & sym = var.getSymbol();
+            const ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getName());
+            const symbol::Symbol & sym = var.getSymbol();
             const std::wstring & name = sym.getName();
             Info & info = getSymInfo(sym); // that put the sym in the current block !
            Result & res = e.getName().getDecorator().setResult(info.type);
@@ -383,7 +394,7 @@ private:
                 }
 
                 // Special analysis cases: size, zeros, ones, ...
-                MapSymCall::iterator it = symscall.find(sym.getName());
+                MapSymCall::iterator it = symscall.find(name);
                 if (it != symscall.end())
                 {
                     if (getCM().checkGlobalConstant(sym) && it->second.get()->analyze(*this, lhs, e))
@@ -545,22 +556,11 @@ private:
         if (e.getInit().isListExp())
         {
             ast::ListExp & le = static_cast<ast::ListExp &>(e.getInit());
-            double start, step, end;
-            if (asDouble(le.getStart(), start) && asDouble(le.getStep(), step) && asDouble(le.getEnd(), end))
-            {
-                ForList64 fl(start, step, end);
-                e.setListInfo(fl);
-                dm.define(sym, fl.getType(), &e).isint = true;
-                // No need to visit the list (it has been visited just before)
-            }
-            else
-            {
-                e.setListInfo(ForList64());
-                le.accept(*this);
-                Result & res = getResult();
-                Info & info = dm.define(sym, res.getType(), &e);
-                info.setRange(res.getRange());
-            }
+           e.setListInfo(ForList64());
+           le.accept(*this);
+           Result & res = getResult();
+           Info & info = dm.define(sym, res.getType(), res.isAnInt(), &e);
+           info.setRange(res.getRange());
         }
     }
 
index ef6944c..ed0359d 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef __DECORATOR_HXX__
 #define __DECORATOR_HXX__
 
-#include "Call.hxx"
+#include "call/Call.hxx"
 #include "Result.hxx"
 
 #include <iostream>
@@ -30,8 +30,9 @@ struct Decorator
     bool hasRefCount;
     bool safeIndex;
     bool safeInsertion;
+    bool safe;
 
-    Decorator() : res(), call(nullptr), cloneData(false), deleteData(false), hasRefCount(false), safeIndex(false), safeInsertion(false) { }
+    Decorator() : res(), call(nullptr), cloneData(false), deleteData(false), hasRefCount(false), safeIndex(false), safeInsertion(false), safe(false) { }
 
     ~Decorator()
     {
@@ -98,7 +99,8 @@ struct Decorator
             << L", Del:" << (deco.deleteData ? L"T" : L"F")
             << L", RefC:" << (deco.hasRefCount ? L"T" : L"F")
             << L", SafeIndex:" << (deco.safeIndex ? L"T" : L"F")
-            << L", SafeInsertion:" << (deco.safeInsertion ? L"T" : L"F");
+            << L", SafeInsertion:" << (deco.safeInsertion ? L"T" : L"F")
+           << L", Safe:" << (deco.safe ? L"T" : L"F");
 
         return out;
     }
diff --git a/scilab/modules/ast/includes/analysis/FBlockEmittedListener.hxx b/scilab/modules/ast/includes/analysis/FBlockEmittedListener.hxx
new file mode 100644 (file)
index 0000000..115224f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  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 __FBLOCK_EMITTED_LISTENER_HXX__
+#define __FBLOCK_EMITTED_LISTENER_HXX__
+
+#include "data/FunctionBlock.hxx"
+
+namespace analysis
+{
+
+class EXTERN_AST FBlockEmittedListener
+{
+
+public:
+
+    virtual void action(FunctionBlock & fblock) = 0;
+};
+
+} // namespace analysis
+
+#endif // __FBLOCK_EMITTED_LISTENER_HXX__
index 4dd97d3..01c8560 100644 (file)
@@ -109,44 +109,6 @@ public:
         return std::is_integral<U>::value ? tools::trunc(max) : max;
     }
 
-    inline TIType getType() const
-    {
-        /*
-            if (isempty())
-            {
-                return TIType(TIType::EMPTY);
-            }
-
-            if (is_int())
-            {
-                if (is_uint())
-                {
-                    if (std::is_same<T, int32_t>::value)
-                    {
-                        return TIType(TIType::UINT32);
-                    }
-                    else
-                    {
-                        return TIType(TIType::UINT64);
-                    }
-                }
-                else
-                {
-                    if (std::is_same<T, int64_t>::value)
-                    {
-                        return TIType(TIType::INT32);
-                    }
-                    else
-                    {
-                        return TIType(TIType::INT64);
-                    }
-                }
-            }
-        */
-
-        return TIType(TIType::DOUBLE);
-    }
-
     friend std::wostream & operator<<(std::wostream & out, const ForList & fl)
     {
         out << L"ForList: { m: " << fl.min << L", s: " << fl.step << L", M: " << fl.max << L", int: " << (fl._int ? L"T" : L"F") << L", uint: " << (fl._unsigned ? L"T" : L"F");
index 4546831..1c73fad 100644 (file)
@@ -76,6 +76,16 @@ public:
         return tempId;
     }
 
+    inline bool isTemp() const
+       {
+           return tempId != -1;
+       }
+
+    inline bool hasGVNValue() const
+       {
+           return constant.getGVNValue() != nullptr;
+       }
+
     inline ConstantValue & getConstant()
     {
         return constant;
@@ -114,6 +124,11 @@ public:
         return range;
     }
 
+    inline bool isAnInt() const
+       {
+           return hasGVNValue() || getRange().isValid();
+       }
+
     inline SymbolicDimension & getMaxIndex()
        {
            return maxIndex;
@@ -138,7 +153,10 @@ public:
     
     friend std::wostream & operator<<(std::wostream & out, const Result & res)
     {
-        out << L"Result {" << res.type << L", temp id:" << res.tempId << L", constant:" << res.constant << L"}";
+        out << L"Result {" << res.type
+           << L", temp id:" << res.tempId
+           << L", constant:" << res.constant
+           << L", isAnInt:" << (res.isAnInt() ? L"T" : L"F") << L"}";
         return out;
     }
 };
index c8bde34..7e8949f 100644 (file)
 
 namespace analysis
 {
-struct TIType
-{
-    static const std::wstring _boolean_, _ce_, _constant_, _fptr_, _function_, _int16_, _int32_, _int64_, _int8_, _library_, _list_, _mlist_, _polynomial_, _sparse_, _st_, _string_, _tlist_, _uint16_, _uint32_, _uint64_, _uint8_, _unknown_;
-
-    enum Type { EMPTY = 0, BOOLEAN, COMPLEX, CELL, DOUBLE, FUNCTION, INT16, INT32, INT64, INT8, LIST, LIBRARY, MACRO, MACROFILE, MLIST, POLYNOMIAL, STRING, SPARSE, STRUCT, TLIST, UNKNOWN, UINT16, UINT32, UINT64, UINT8, COUNT };
-    Type type;
-    SymbolicDimension rows;
-    SymbolicDimension cols;
-    bool scalar;
-
-    TIType(const Type _type = UNKNOWN) : type(_type), scalar(true) { }
-    TIType(GVN & gvn) : type(UNKNOWN), rows(gvn, 0.), cols(gvn, 0.), scalar(false) { }
-    TIType(GVN & gvn, const Type _type) : type(_type), rows(gvn, _type == EMPTY ? 0 : 1), cols(gvn, _type == EMPTY ? 0 : 1), scalar(_type != EMPTY) { }
-    TIType(GVN & gvn, const Type _type, const int _rows, const int _cols) : type(_type), rows(gvn, _rows), cols(gvn, _cols), scalar(_rows == 1 && _cols == 1) { }
-    TIType(GVN & gvn, Type _type, const SymbolicDimension & _rows, const SymbolicDimension & _cols) : type(_type), rows(_rows), cols(_cols), scalar(_rows == 1 && _cols == 1) { }
-    TIType(GVN & gvn, const Type _type, const bool _scalar) : type(_type), rows(gvn, _scalar ? 1. : -1.), cols(gvn, _scalar ? 1. : -1.), scalar(_scalar) { }
-
-    inline bool hasValidDims() const
-    {
-        return rows != -2 && cols != -2;
-    }
-
-    inline bool hasInvalidDims() const
-    {
-        return rows == -2;
-    }
-
-    inline TIType asUnknownMatrix()
-    {
-        return TIType(*rows.getGVN(), type, false);
-    }
-
-    inline bool isscalar() const
-    {
-        return scalar;
-    }
-
-    inline void invalidScalar()
-    {
-        scalar = rows == 1 && cols == 1;
-    }
-
-    inline bool iscomplex() const
-    {
-        return type == COMPLEX;
-    }
+    struct TIType
+    {
+        static const std::wstring _boolean_, _ce_, _constant_, _fptr_, _function_, _int16_, _int32_, _int64_, _int8_, _library_, _list_, _mlist_, _polynomial_, _sparse_, _st_, _string_, _tlist_, _uint16_, _uint32_, _uint64_, _uint8_, _unknown_;
+        
+        enum Type { EMPTY = 0, BOOLEAN, COMPLEX, CELL, DOUBLE, FUNCTION, INT16, INT32, INT64, INT8, LIST, LIBRARY, MACRO, MACROFILE, MLIST, POLYNOMIAL, STRING, SPARSE, STRUCT, TLIST, UNKNOWN, UINT16, UINT32, UINT64, UINT8, COUNT };
+        Type type;
+       SymbolicDimension rows;
+       SymbolicDimension cols;
+        bool scalar;
+
+       TIType(const Type _type = UNKNOWN) : type(_type), scalar(true) { }
+        TIType(GVN & gvn) : type(UNKNOWN), rows(gvn, 0.), cols(gvn, 0.), scalar(false) { }
+        TIType(GVN & gvn, const Type _type) : type(_type), rows(gvn, _type == EMPTY ? 0 : 1), cols(gvn, _type == EMPTY ? 0 : 1), scalar(_type != EMPTY) { }
+       TIType(GVN & gvn, const Type _type, const int _rows, const int _cols) : type(_type), rows(gvn, _rows), cols(gvn, _cols), scalar(_rows == 1 && _cols == 1) { }
+       TIType(GVN & gvn, Type _type, const SymbolicDimension & _rows, const SymbolicDimension & _cols) : type(_type), rows(_rows), cols(_cols), scalar(_rows == 1 && _cols == 1) { }
+       TIType(GVN & gvn, const Type _type, const bool _scalar) : type(_type), rows(gvn, _scalar ? 1. : -1.), cols(gvn, _scalar ? 1. : -1.), scalar(_scalar) { }
+
+       inline bool hasValidDims() const
+       {
+           return rows != -2 && cols != -2;
+       }
+
+       inline bool hasInvalidDims() const
+       {
+           return rows == -2;
+       }
+
+       inline TIType asUnknownMatrix()
+       {
+           return TIType(*rows.getGVN(), type, false);
+       }
+
+        inline bool isscalar() const
+        {
+            return scalar;
+        }
 
-    inline bool isreal() const
-    {
-        return type == DOUBLE;
-    }
+        inline void invalidScalar()
+        {
+            scalar = rows == 1 && cols == 1;
+        }
 
-    inline bool isintegral() const
-    {
-        return type == BOOLEAN || type == INT8 || type == INT16 || type == INT32 || type == INT64 || type == UINT8 || type == UINT16 || type == UINT32 || type == UINT64;
-    }
+        inline bool iscomplex() const
+        {
+            return type == COMPLEX;
+        }
 
-    inline bool ismatrix() const
-    {
-        return type != CELL && type != FUNCTION && type != LIST && type != LIBRARY && type != MACRO && type != MACROFILE && type != MLIST && type != STRUCT && type != TLIST && type != UNKNOWN;
-    }
+        inline bool isreal() const
+        {
+            return type == DOUBLE;
+        }
 
-    inline bool issigned() const
-    {
-        return type != UINT8 && type != UINT16 && type != UINT32 && type != UINT64;
-    }
+        inline bool isintegral() const
+        {
+            return type == BOOLEAN || type == INT8 || type == INT16 || type == INT32 || type == INT64 || type == UINT8 || type == UINT16 || type == UINT32 || type == UINT64;
+        }
 
-    inline bool isfloating() const
-    {
-        return type == DOUBLE || type == COMPLEX;
-    }
+        inline bool ismatrix() const
+        {
+            return type != CELL && type != FUNCTION && type != LIST && type != LIBRARY && type != MACRO && type != MACROFILE && type != MLIST && type != STRUCT && type != TLIST && type != UNKNOWN;
+        }
 
-    inline bool isKnownDims() const
-    {
-        return rows.isValid() && cols.isValid();
-    }
+        inline bool issigned() const
+        {
+            return type != UINT8 && type != UINT16 && type != UINT32 && type != UINT64;
+        }
 
-    inline bool isUnknownDims() const
-    {
-        return !isKnownDims();
-    }
+       inline bool isfloating() const
+       {
+           return type == DOUBLE || type == COMPLEX;
+       }
 
-    inline bool isknown() const
-    {
-        return type != UNKNOWN;
-    }
+        inline bool isKnownDims() const
+        {
+            return rows.isValid() && cols.isValid();
+        }
 
-    inline bool isunknown() const
-    {
-        return type == UNKNOWN;
-    }
+        inline bool isUnknownDims() const
+        {
+            return !isKnownDims();
+        }
 
-    inline bool isConstantDims() const
-    {
-        return rows.isConstant() && cols.isConstant();
-    }
+        inline bool isknown() const
+        {
+            return type != UNKNOWN;
+        }
 
-    inline void swapDims()
-    {
-        GVN::Value * r = rows.getValue();
-        rows.setValue(cols.getValue());
-        cols.setValue(r);
-    }
+        inline bool isunknown() const
+        {
+            return type == UNKNOWN;
+        }
 
-    inline std::size_t hashPureType() const
-    {
-        return isscalar() ? type : (type + TIType::COUNT + 1);
-    }
+        inline bool isConstantDims() const
+        {
+            return rows.isConstant() && cols.isConstant();
+        }
 
-    inline bool operator==(const TIType & r) const
-    {
-        return type == r.type && scalar == r.scalar && rows == r.rows && cols == r.cols;
-    }
+        inline void swapDims()
+        {
+            GVN::Value * r = rows.getValue();
+            rows.setValue(cols.getValue());
+            cols.setValue(r);
+        }
 
-    inline bool operator!=(const TIType & r) const
-    {
-        return !(*this == r);
-    }
+       inline std::size_t hashPureType() const
+       {
+            return isscalar() ? type : (type + TIType::COUNT + 1);
+       }
 
-    inline void merge(const TIType & type)
-    {
-        if (this->type == DOUBLE && type.type == COMPLEX)
+        inline bool operator==(const TIType & r) const
         {
-            this->type = COMPLEX;
+            return type == r.type && scalar == r.scalar && rows == r.rows && cols == r.cols;
         }
-        else if ((this->type != COMPLEX || type.type != DOUBLE) && this->type != type.type)
+
+        inline bool operator!=(const TIType & r) const
         {
-            this->type = UNKNOWN;
-            rows.setValue(0.);
-            cols.setValue(0.);
+            return !(*this == r);
         }
-        else if ((!scalar || !type.scalar) && (rows != type.rows || cols != type.cols))
+
+       inline void merge(const TIType & type)
         {
-            if (rows != type.rows)
+            if (this->type == DOUBLE && type.type == COMPLEX)
             {
-                rows.setValue(rows.getGVN()->getValue());
+               this->type = COMPLEX;
             }
-            if (cols != type.cols)
-            {
-                cols.setValue(cols.getGVN()->getValue());
-            }
-            scalar = false;
-        }
-        /*else if ((!scalar || !type.scalar) && (rows != type.rows || cols != type.cols))
-        {
-        rows.invalid();
-        cols.invalid();
-        scalar = false;
-        }*/
-    }
-
-    template<typename> static Type getTI();
-
-    inline std::string get_mangling() const
-    {
-        const bool kd = isKnownDims();
-        switch (type)
+           else if ((this->type != COMPLEX || type.type != DOUBLE) && this->type != type.type) 
+           {
+               this->type = UNKNOWN;
+               rows.setValue(0.);
+               cols.setValue(0.);
+           }
+           else if ((!scalar || !type.scalar) && (rows != type.rows || cols != type.cols))
+           {
+               if (rows != type.rows)
+               {
+                   rows.setValue(rows.getGVN()->getValue());
+               }
+               if (cols != type.cols)
+               {
+                   cols.setValue(cols.getGVN()->getValue());
+               }
+               scalar = false;
+           }
+           /*else if ((!scalar || !type.scalar) && (rows != type.rows || cols != type.cols))
+           {
+               rows.invalid();
+               cols.invalid();
+               scalar = false;
+           }*/
+       }
+
+       template<typename> static Type getTI();
+
+        inline std::string get_mangling() const
         {
+            const bool kd = isKnownDims();
+            switch (type)
+            {
             case EMPTY :
                 return "E";
             case BOOLEAN :
@@ -235,64 +235,123 @@ struct TIType
                 return kd ? (scalar ? "S_ui8" : "M_ui8") : "U_ui8";
             default :
                 return "??";
+            }
         }
-    }
 
-    inline static std::string get_unary_mangling(const std::string & pre, const TIType & l)
-    {
-        return pre + "_" + l.get_mangling();
-    }
+        inline static std::string get_mangling(const TIType::Type ty, const bool scalar)
+        {
+            switch (ty)
+            {
+            case EMPTY :
+                return "E";
+            case BOOLEAN :
+                return scalar ? "S_b" : "M_b";
+            case COMPLEX :
+                return scalar ? "S_c" : "M_c";
+            case CELL :
+                return scalar ? "S_ce" : "M_ce";
+            case DOUBLE :
+                return scalar ? "S_d" : "M_d";
+            case FUNCTION :
+                return scalar ? "S_fn" : "M_fn";
+            case INT16 :
+                return scalar ? "S_i16" : "M_i16";
+            case INT32 :
+                return scalar ? "S_i32" : "M_i32";
+            case INT64 :
+                return scalar ? "S_i64" : "M_i64";
+            case INT8 :
+                return scalar ? "S_i8" : "M_i8";
+            case LIST :
+                return scalar ? "S_l" : "M_l";
+            case LIBRARY :
+                return scalar ? "S_lb" : "M_lb";
+            case MACRO :
+                return scalar ? "S_m" : "M_m";
+            case MACROFILE :
+                return scalar ? "S_mf" : "M_mf";
+            case MLIST :
+                return scalar ? "S_ml" : "M_ml";
+            case POLYNOMIAL :
+                return scalar ? "S_p" : "M_p";
+            case STRING :
+                return scalar ? "S_s" : "M_s";
+            case SPARSE :
+                return scalar ? "S_sp" : "M_sp";
+            case STRUCT :
+                return scalar ? "S_st" : "M_st";
+            case TLIST :
+                return scalar ? "S_tl" : "M_tl";
+            case UNKNOWN :
+                return scalar ? "S_u" : "M_u";
+            case UINT16 :
+                return scalar ? "S_ui16" : "M_ui16";
+            case UINT32 :
+                return scalar ? "S_ui32" : "M_ui32";
+            case UINT64 :
+                return scalar ? "S_ui64" : "M_ui64";
+            case UINT8 :
+                return scalar ? "S_ui8" : "M_ui8";
+            default :
+                return "??";
+            }
+        }
 
-    inline static std::string get_binary_mangling(const std::string & pre, const TIType & l, const TIType & r)
-    {
-        return pre + "_" + l.get_mangling() + "_" + r.get_mangling();
-    }
+        inline static std::string get_unary_mangling(const std::string & pre, const TIType & l)
+        {
+            return pre + "_" + l.get_mangling();
+        }
 
-    inline static std::string get_mangling(const std::string & pre, const std::vector<TIType> & types)
-    {
-        std::string s(pre);
-        for (std::vector<TIType>::const_iterator i = types.begin(), end = types.end(); i != end; ++i)
+        inline static std::string get_binary_mangling(const std::string & pre, const TIType & l, const TIType & r)
         {
-            s += "_" + i->get_mangling();
+            return pre + "_" + l.get_mangling() + "_" + r.get_mangling();
         }
-        return s;
-    }
 
-    inline static unsigned int get_base_size(const Type type)
-    {
-        switch (type)
+        inline static std::string get_mangling(const std::string & pre, const std::vector<TIType> & types)
         {
+           std::string s(pre);
+           for (std::vector<TIType>::const_iterator i = types.begin(), end = types.end(); i != end; ++i)
+           {
+               s += "_" + i->get_mangling();
+           }
+            return s;
+        }
+
+        inline static unsigned int get_base_size(const Type type)
+        {
+            switch (type)
+            {
             case EMPTY :
                 return sizeof(double);
             case BOOLEAN :
                 return sizeof(int);
             case DOUBLE :
                 return sizeof(double);
-            case INT8 :
-                return sizeof(int8_t);
-            case INT16 :
-                return sizeof(int16_t);
+           case INT8 :
+               return sizeof(int8_t);
+           case INT16 :
+               return sizeof(int16_t);
             case INT32 :
-                return sizeof(int32_t);
+               return sizeof(int32_t);
             case INT64 :
-                return sizeof(int64_t);
-            case UINT8 :
-                return sizeof(uint8_t);
-            case UINT16 :
-                return sizeof(uint16_t);
+               return sizeof(int64_t);
+           case UINT8 :
+               return sizeof(uint8_t);
+           case UINT16 :
+               return sizeof(uint16_t);
             case UINT32 :
-                return sizeof(uint32_t);
+               return sizeof(uint32_t);
             case UINT64 :
-                return sizeof(uint64_t);
+               return sizeof(uint64_t);
             default :
                 return 0;
+            }
         }
-    }
 
-    inline static std::wstring toString(Type t)
-    {
-        switch (t)
+        inline static std::wstring toString(Type t)
         {
+            switch (t)
+            {
             case EMPTY :
                 return L"[]";
             case BOOLEAN :
@@ -345,18 +404,18 @@ struct TIType
                 return L"uint8";
             default :
                 return L"unknown";
+            }
         }
-    }
 
-    inline const std::wstring & getScilabString() const
-    {
-        return getScilabString(type);
-    }
+        inline const std::wstring & getScilabString() const
+        {
+            return getScilabString(type);
+        }
 
-    inline static const std::wstring & getScilabString(Type t)
-    {
-        switch (t)
+        inline static const std::wstring & getScilabString(Type t)
         {
+            switch (t)
+            {
             case EMPTY :
                 return _constant_;
             case BOOLEAN :
@@ -409,18 +468,18 @@ struct TIType
                 return _uint8_;
             default :
                 return _unknown_;
+            }
         }
-    }
 
-    inline int getScilabCode() const
-    {
-        return getScilabCode(type);
-    }
+        inline int getScilabCode() const
+        {
+            return getScilabCode(type);
+        }
 
-    inline static int getScilabCode(Type t)
-    {
-        switch (t)
+        inline static int getScilabCode(Type t)
         {
+            switch (t)
+            {
             case EMPTY :
                 return 1;
             case BOOLEAN :
@@ -473,13 +532,13 @@ struct TIType
                 return 8;
             default :
                 return -1;
+            }
         }
-    }
 
-    friend std::wostream & operator<<(std::wostream & out, const TIType & type)
-    {
-        switch (type.type)
+       friend std::wostream & operator<<(std::wostream & out, const TIType & type)
         {
+            switch (type.type)
+            {
             case EMPTY :
                 out << L"[]";
                 break;
@@ -557,78 +616,48 @@ struct TIType
                 break;
             default :
                 break;
-        }
-
-        if (type.type != EMPTY && type.type != UNKNOWN)
-        {
-            if (type.isUnknownDims())
-            {
-                out << L"[?, ?]";
             }
-            else
+
+            if (type.type != EMPTY && type.type != UNKNOWN)
             {
-                out << L"[" << type.rows << L", " << type.cols << L"]";
-            }
+                if (type.isUnknownDims())
+                {
+                    out << L"[?, ?]";
+                }
+                else
+                {
+                    out << L"[" << type.rows << L", " << type.cols << L"]";
+                }
+           }
+
+            return out;
         }
-
-        return out;
-    }
-};
-
-template<> inline TIType::Type TIType::getTI<bool>()
-{
-    return TIType::BOOLEAN;
-}
-template<> inline TIType::Type TIType::getTI<double>()
-{
-    return TIType::DOUBLE;
-}
-template<> inline TIType::Type TIType::getTI<int16_t>()
-{
-    return TIType::INT16;
-}
-template<> inline TIType::Type TIType::getTI<int32_t>()
-{
-    return TIType::INT32;
-}
-template<> inline TIType::Type TIType::getTI<int64_t>()
-{
-    return TIType::INT64;
-}
-template<> inline TIType::Type TIType::getTI<int8_t>()
-{
-    return TIType::INT8;
-}
-template<> inline TIType::Type TIType::getTI<uint16_t>()
-{
-    return TIType::UINT16;
-}
-template<> inline TIType::Type TIType::getTI<uint32_t>()
-{
-    return TIType::UINT32;
-}
-template<> inline TIType::Type TIType::getTI<uint64_t>()
-{
-    return TIType::UINT64;
-}
-template<> inline TIType::Type TIType::getTI<uint8_t>()
-{
-    return TIType::UINT8;
-}
+    };
+
+    template<> inline TIType::Type TIType::getTI<bool>() { return TIType::BOOLEAN; }
+    template<> inline TIType::Type TIType::getTI<double>() { return TIType::DOUBLE; }
+    template<> inline TIType::Type TIType::getTI<int16_t>() { return TIType::INT16; }
+    template<> inline TIType::Type TIType::getTI<int32_t>() { return TIType::INT32; }
+    template<> inline TIType::Type TIType::getTI<int64_t>() { return TIType::INT64; }
+    template<> inline TIType::Type TIType::getTI<int8_t>() { return TIType::INT8; }
+    template<> inline TIType::Type TIType::getTI<uint16_t>() { return TIType::UINT16; }
+    template<> inline TIType::Type TIType::getTI<uint32_t>() { return TIType::UINT32; }
+    template<> inline TIType::Type TIType::getTI<uint64_t>() { return TIType::UINT64; }
+    template<> inline TIType::Type TIType::getTI<uint8_t>() { return TIType::UINT8; }
 
 } // namespace analysis
 
 namespace std
 {
-// useful to be able to put TIType in unorderd_set for example.
-template<>
-struct hash<analysis::TIType>
-{
-    inline size_t operator()(const analysis::TIType & t) const
-    {
-        return 0;//tools::hash_combine(t.type, t.rows, t.cols);
-    }
-};
+    // useful to be able to put TIType in unorderd_set for example.
+    template<>
+    struct hash<analysis::TIType>
+    {
+       inline size_t operator()(const analysis::TIType & t) const
+           {
+               return 0;//tools::hash_combine(t.type, t.rows, t.cols);
+           }
+    };
 } // namespace std
 
 #endif // __TITYPE_HXX__
\ No newline at end of file
diff --git a/scilab/modules/ast/includes/analysis/Temporary.hxx b/scilab/modules/ast/includes/analysis/Temporary.hxx
deleted file mode 100644 (file)
index 17bb5be..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
- *
- *  This file must be used under the terms of the CeCILL.
- *  This source file is licensed as described in the file COPYING, which
- *  you should have received as part of this distribution.  The terms
- *  are also available at
- *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- */
-
-#ifndef __TEMPORARY_HXX__
-#define __TEMPORARY_HXX__
-
-#include <iostream>
-#include <set>
-#include <stack>
-#include <unordered_map>
-#include <vector>
-
-#include "TIType.hxx"
-#include "Result.hxx"
-
-namespace analysis
-{
-
-/* Class to count the number of required temporary variables
-   We have two kinds of temporary: sized and non-sized (sized temp are just temp vars which we know the dims).
-   The strategy to choose a sized temp is the following:
-   i) we look for an existing temp (but not used) with enough storage
-   ii) if such a one doesn't exist we take the last one and we increase its size or we create a new one.
-   The idea is to allocate enough memory for all the temps before to execution.
- */
-class Temporary
-{
-    struct __Temporary
-    {
-        struct __Sized_Temp
-        {
-            const int id;
-            const unsigned int size;
-
-            __Sized_Temp(const int _id, const unsigned int _size) : id(_id), size(_size) { }
-            __Sized_Temp(const unsigned int _size) : id(0), size(_size) { }
-
-            struct __Compare
-            {
-                inline std::size_t operator()(const __Sized_Temp & l, const __Sized_Temp & r) const
-                {
-                    return l.size < r.size;
-                }
-            };
-        };
-
-        typedef std::set<__Sized_Temp, __Sized_Temp::__Compare> SizedSet;
-        SizedSet free_sized_ids;
-        std::unordered_map<int, __Sized_Temp> used_sized_ids;
-        std::stack<int> free_nonsized_ids;
-        int max;
-        int nonsized_max;
-
-        __Temporary() : max(0), nonsized_max(-2) { }
-
-        inline void remove(int id)
-        {
-            std::unordered_map<int, __Sized_Temp>::const_iterator i = used_sized_ids.find(id);
-            if (i != used_sized_ids.end())
-            {
-                free_sized_ids.insert(i->second);
-                used_sized_ids.erase(i);
-            }
-            else if (id <= -2)
-            {
-                free_nonsized_ids.push(id);
-            }
-        }
-
-        inline int getId()
-        {
-            int id;
-            if (free_nonsized_ids.empty())
-            {
-                id = max++;//nonsized_max--;
-            }
-            else
-            {
-                id = free_nonsized_ids.top();
-                free_nonsized_ids.pop();
-            }
-
-            return id;
-        }
-
-        inline int getId(int size)
-        {
-            SizedSet::iterator i = free_sized_ids.lower_bound(__Sized_Temp(size));
-            if (i != free_sized_ids.end())
-            {
-                const int id = i->id;
-                used_sized_ids.emplace(std::pair<int, __Sized_Temp>(id, *i));
-                free_sized_ids.erase(i);
-
-                return id;
-            }
-            else
-            {
-                if (free_sized_ids.empty())
-                {
-                    const int id = max++;
-                    used_sized_ids.emplace(std::pair<int, __Sized_Temp>(id, __Sized_Temp(id, size)));
-                    return id;
-                }
-                else
-                {
-                    SizedSet::const_iterator last = --free_sized_ids.begin();
-                    const int id = last->id;
-                    used_sized_ids.emplace(std::pair<int, __Sized_Temp>(id, __Sized_Temp(id, size)));
-                    free_sized_ids.erase(last);
-
-                    return id;
-                }
-            }
-        }
-
-        inline std::vector<int64_t> getSizes(int64_t & totalSize) const
-        {
-            std::vector<int64_t> v(max, -1);
-            unsigned int total = 0;
-            for (const auto & st : free_sized_ids)
-            {
-                total += st.size;
-                v[st.id] = st.size;
-            }
-            for (const auto & kv : used_sized_ids)
-            {
-                total += kv.second.size;
-                v[kv.second.id] = kv.second.size;
-            }
-
-            totalSize = total;
-            return v;
-        }
-
-        inline unsigned int totalSize() const
-        {
-            unsigned int total = 0;
-            for (const auto & st : free_sized_ids)
-            {
-                total += st.size;
-            }
-            for (const auto & kv : used_sized_ids)
-            {
-                total += kv.second.size;
-            }
-
-            return total;
-        }
-    };
-
-    __Temporary scalars[TIType::COUNT];
-    __Temporary matrices[TIType::COUNT];
-
-public:
-
-    Temporary() { }
-
-    inline int add(const TIType & t, const bool scalar = false)
-    {
-        if (t.isKnownDims() && t.isConstantDims())
-        {
-            return scalar ? scalars[t.type].getId(1) : matrices[t.type].getId((int) (t.rows.getConstant() * t.cols.getConstant()));
-        }
-        else
-        {
-            return scalar ? scalars[t.type].getId() : matrices[t.type].getId();
-        }
-    }
-
-    inline void remove(const TIType & t, const int id, const bool scalar = false)
-    {
-        if (id >= 0)
-        {
-            if (scalar)
-            {
-                scalars[t.type].remove(id);
-            }
-            else
-            {
-                matrices[t.type].remove(id);
-            }
-        }
-    }
-
-    inline void remove(const Result & r)
-    {
-        remove(r.getType(), r.getTempId());
-    }
-
-    inline int get_scalar(const TIType::Type t) const
-    {
-        return scalars[t].max;
-    }
-
-    inline int get_matrix(const TIType::Type t) const
-    {
-        return matrices[t].max;
-    }
-
-    inline unsigned int totalSize(const TIType::Type t) const
-    {
-        return matrices[t].totalSize();
-    }
-
-    inline std::vector<int64_t> getSizes(const TIType::Type t, int64_t & totalSize) const
-    {
-        return matrices[t].getSizes(totalSize);
-    }
-
-    friend std::wostream & operator<<(std::wostream & out, const Temporary & temp)
-    {
-        bool hasTmpScal = false;
-        bool hasTmpMat = false;
-        for (unsigned int i = 0; i < TIType::COUNT; ++i)
-        {
-            if (temp.get_scalar(static_cast<TIType::Type>(i)))
-            {
-                hasTmpScal = true;
-                break;
-            }
-        }
-
-        for (unsigned int i = 0; i < TIType::COUNT; ++i)
-        {
-            if (temp.get_matrix(static_cast<TIType::Type>(i)))
-            {
-                hasTmpMat = true;
-                break;
-            }
-        }
-
-        if (hasTmpScal)
-        {
-            out << L"Temporary scalars:" << std::endl;
-            for (unsigned int i = 0; i < TIType::COUNT; ++i)
-            {
-                const TIType::Type t = static_cast<TIType::Type>(i);
-                if (temp.get_scalar(t))
-                {
-                    out << TIType(t) << ": " << temp.get_scalar(t) << std::endl;
-                }
-            }
-        }
-
-        if (hasTmpMat)
-        {
-            out << std::endl
-                << L"Temporary arrays:" << std::endl;
-
-            for (unsigned int i = 0; i < TIType::COUNT; ++i)
-            {
-                const TIType::Type t = static_cast<TIType::Type>(i);
-                if (temp.get_matrix(t))
-                {
-                    out << TIType(t) << ": " << temp.get_matrix(t) << " (total size: " << temp.totalSize(t) << ")" << std::endl;
-                }
-            }
-        }
-
-        if (hasTmpScal || hasTmpMat)
-        {
-            out << std::endl;
-        }
-        return out;
-    }
-};
-
-} // namespace analysis
-
-#endif // __TEMPORARY_HXX__
@@ -24,7 +24,7 @@ namespace analysis
     class Call
     {
 
-    private:
+    protected:
 
         const std::wstring name;
         std::vector<TIType> args;
diff --git a/scilab/modules/ast/includes/analysis/call/SizeCall.hxx b/scilab/modules/ast/includes/analysis/call/SizeCall.hxx
new file mode 100644 (file)
index 0000000..433ce70
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  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 __SIZE_CALL_HXX__
+#define __SIZE_CALL_HXX__
+
+#include "Call.hxx"
+
+namespace analysis
+{
+    class SizeCall : public Call
+    {
+
+    public:
+
+       enum Kind { R, C, RC, R_C, ONE, BOTH, DUNNO };
+
+    private:
+       
+       Kind kind;
+       
+    public:
+
+        SizeCall(Kind _kind) : Call(L"size"), kind(_kind) { }
+
+       inline Kind getKind() const
+           {
+               return kind;
+           }
+    };
+
+} // namespace analysis
+
+#endif // __SIZE_CALL_HXX__
index d859da0..9e13b79 100644 (file)
@@ -118,9 +118,12 @@ namespace analysis
         Info & putSymsInScope(const symbol::Symbol & sym, Block * block, Info & info);
         Info & putSymsInScope(const symbol::Symbol & sym);
 
+       virtual void addLocal(const symbol::Symbol & sym, const TIType & type, const bool isIntIterator);
+       virtual int getTmpId(const TIType & type, const bool isIntIterator);
+       virtual void releaseTmp(const int id);
         virtual Info & addRead(const symbol::Symbol & sym, ast::Exp * exp);
         virtual Info & addWrite(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp);
-        virtual Info & addDefine(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp);
+        virtual Info & addDefine(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp);
         virtual Info & addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp);
         virtual Info & addMacroDef(ast::FunctionDec * dec);
         virtual std::vector<TIType> addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp);
index 33b12cc..8141622 100644 (file)
@@ -17,6 +17,7 @@
 #include <stack>
 #include <set>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 //#define DEBUG_DATAMANAGER
@@ -42,12 +43,13 @@ namespace analysis
     {
         friend class Block;
 
-        Block * root;
+       Block * root;
         Block * current;
         std::vector<Data *> data;
         unsigned int id;
         std::set<symbol::Symbol> globals;
         std::stack<FunctionBlock *> callStack;
+       std::unordered_map<types::Macro *, MacroDef *> macroDefCache;
         GVN gvn;
 
     public:
@@ -59,14 +61,15 @@ namespace analysis
 
         ~DataManager()
             {
-                //std::cerr << "delete DataManager: begin" << std::endl;
                 for (const auto d : data)
                 {
-                    //std::cout << "ptr delete=" << d << std::endl;
                     delete d;
                 }
                 delete root;
-                //std::cerr << "delete DataManager: end" << std::endl;
+               for (const auto & p : macroDefCache)
+               {
+                   delete p.second;
+               }
             }
 
         inline GVN & getGVN()
@@ -79,6 +82,16 @@ namespace analysis
                 return gvn;
             }
 
+       inline MacroDef * getMacroDef(types::Macro * macro)
+           {
+               auto i = macroDefCache.find(macro);
+               if (i == macroDefCache.end())
+               {
+                   i = macroDefCache.emplace(macro, new ExistingMacroDef(*macro)).first;
+               }
+               return i->second;
+           }
+       
         inline void addGlobal(const symbol::Symbol & sym)
             {
                 globals.emplace(sym);
@@ -104,6 +117,16 @@ namespace analysis
                 }
             }
 
+       inline int getTmpId(const TIType & type, const bool isAnInt)
+           {
+               return current->getTmpId(type, isAnInt);
+           }
+       
+       inline void releaseTmp(const int id)
+           {
+               current->releaseTmp(id);
+           }
+       
         inline Info & read(const symbol::Symbol & sym, ast::Exp * exp)
             {
                 return current->addRead(sym, exp);
@@ -114,9 +137,9 @@ namespace analysis
                 return current->addWrite(sym, Rtype, exp);
             }
 
-        inline Info & define(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
+        inline Info & define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
             {
-                return current->addDefine(sym, Rtype, exp);
+                return current->addDefine(sym, Rtype, isAnInt, exp);
             }
 
         inline Info & share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
index ec683e3..99b0706 100644 (file)
@@ -21,6 +21,8 @@
 #include "allexp.hxx"
 #include "Block.hxx"
 #include "MacroDef.hxx"
+#include "TypeLocal.hxx"
+#include "TemporaryManager.hxx"
 #include "TITypeSignatureTuple.hxx"
 #include "gvn/ConstraintManager.hxx"
 
@@ -32,36 +34,20 @@ struct MacroOut;
 class FunctionBlock : public Block
 {
 
-    struct __TypeLocal
-    {
-       TIType::Type type;
-       int rows;
-       int cols;
-
-       __TypeLocal(const TIType::Type _type, const int _rows, const int _cols) : type(_type), rows(_rows), cols(_cols) { }
-
-       inline bool operator<(const __TypeLocal & R) const
-           {
-               return type < R.type || (type == R.type && (rows < R.rows || (rows == R.rows && cols < R.cols)));
-           }
-
-       inline bool isScalar() const
-           {
-               return rows == 1 && cols == 1;
-           }
-    };
-    
     std::wstring name;
     std::vector<symbol::Symbol> in;
     std::vector<symbol::Symbol> out;
     std::set<symbol::Symbol> globals;
-    std::map<symbol::Symbol, std::set<__TypeLocal>> locals;
+    std::vector<std::pair<symbol::Symbol, TypeLocal>> types_in;
+    std::vector<std::pair<symbol::Symbol, TypeLocal>> types_out;
+    std::map<symbol::Symbol, std::set<TypeLocal>> locals;
     std::vector<GVN::Value *> inValues;
     unsigned int lhs;
     unsigned int rhs;
     int maxVarId;
     GVN fgvn;
     ConstraintManager constraintManager;
+    TemporaryManager tempManager;
 
 public:
 
@@ -93,33 +79,32 @@ public:
         return rhs;
     }
 
+    inline const std::vector<std::pair<symbol::Symbol, TypeLocal>> & getTypesIn() const
+       {
+           return types_in;
+       }
+
+    inline const std::vector<std::pair<symbol::Symbol, TypeLocal>> & getTypesOut() const
+       {
+           return types_out;
+       }
+
+    inline const std::map<symbol::Symbol, std::set<TypeLocal>> & getTypesLocals() const
+       {
+           return locals;
+       }
+
     inline int getMaxVarId() const
     {
         return maxVarId;
     }
 
-    void finalize() override;
-    void addGlobal(const symbol::Symbol & sym) override;
-    Info & addDefine(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp) override;
-    Block * getDefBlock(const symbol::Symbol & sym, std::map<symbol::Symbol, Info>::iterator & it, const bool global) override;
-
-    bool addIn(const TITypeSignatureTuple & tuple, const std::vector<GVN::Value *> & values);
-    void setGlobals(const std::set<symbol::Symbol> & v);
-    //TITypeSignatureTuple getGlobals(std::vector<symbol::Symbol> & v);
-    MacroOut getOuts();
-
     inline void setLhsRhs(const unsigned int _lhs, const unsigned int _rhs)
     {
         lhs = _lhs;
         rhs = _rhs;
     }
 
-    inline void setInOut(MacroDef * macrodef)
-    {
-        in = macrodef->getIn();
-        out = macrodef->getOut();
-    }
-
     inline const MPolyConstraintSet & getConstraints() const
     {
         return constraintManager.getSet();
@@ -129,6 +114,41 @@ public:
     {
         return constraintManager.getGlobalConstants();
     }
+
+    inline const std::map<TypeLocal, std::stack<int>> & getTemp() const
+       {
+           return tempManager.getTemp();
+       }
+
+    inline const std::map<TypeLocal, int> getTempCount(int & total) const
+       {
+           int _total = 0;
+           std::map<TypeLocal, int> map;
+           for (const auto & p : getTemp())
+           {
+               _total += p.second.size();
+               map.emplace(p.first, p.second.size());
+           }
+
+           total = _total;
+           
+           return map;
+       }
+
+    void finalize() override;
+    void addGlobal(const symbol::Symbol & sym) override;
+    Block * getDefBlock(const symbol::Symbol & sym, std::map<symbol::Symbol, Info>::iterator & it, const bool global) override;
+    void addLocal(const symbol::Symbol & sym, const TIType & type, const bool isAnInt) override;
+    int getTmpId(const TIType & type, const bool isAnInt) override;
+    void releaseTmp(const int id) override;
+
+    bool addIn(const TITypeSignatureTuple & tuple, const std::vector<GVN::Value *> & values);
+    void setGlobals(const std::set<symbol::Symbol> & v);
+    //TITypeSignatureTuple getGlobals(std::vector<symbol::Symbol> & v);
+    MacroOut getOuts();
+    void setInOut(MacroDef * macrodef, const unsigned int rhs, const std::vector<TIType> & _in);
+
+    friend std::wostream & operator<<(std::wostream & out, const FunctionBlock & fblock);
 };
 
 } // namespace analysis
index 8e51087..706cfa9 100644 (file)
@@ -30,16 +30,19 @@ namespace analysis
 class MacroDef
 {
 
+protected:
+    
     const unsigned int lhs;
     const unsigned int rhs;
+    ast::Exp * const original;
 
     std::set<symbol::Symbol> globals;
 
 public:
 
-    MacroDef(const unsigned int _lhs, const unsigned int _rhs) : lhs(_lhs), rhs(_rhs) { }
+    MacroDef(const unsigned int _lhs, const unsigned int _rhs, ast::Exp * _original) : lhs(_lhs), rhs(_rhs), original(_original) { }
     virtual ~MacroDef() { }
-    
+
     virtual ast::SeqExp & getBody() = 0;
     virtual const std::wstring & getName() = 0;
     virtual std::vector<symbol::Symbol> getIn() = 0;
@@ -50,14 +53,22 @@ public:
     {
         return lhs;
     }
+
     inline unsigned int getRhs() const
     {
         return rhs;
     }
+
+    inline ast::Exp * getOriginal() const
+       {
+           return original;
+       }
+    
     inline std::set<symbol::Symbol> & getGlobals()
     {
         return globals;
     }
+
     inline const std::set<symbol::Symbol> & getGlobals() const
     {
         return globals;
@@ -102,7 +113,7 @@ public:
        {
            delete se;
        }
-
+    
     ast::SeqExp & getBody();
     const std::wstring & getName();
     std::vector<symbol::Symbol> getIn();
@@ -112,7 +123,7 @@ public:
 
 class DeclaredMacroDef : public MacroDef
 {
-    ast::FunctionDec * const dec;
+    ast::FunctionDec * dec;
 
 public:
 
diff --git a/scilab/modules/ast/includes/analysis/data/TemporaryManager.hxx b/scilab/modules/ast/includes/analysis/data/TemporaryManager.hxx
new file mode 100644 (file)
index 0000000..e67d9e3
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  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 __TEMPORARY_MANAGER_HXX__
+#define __TEMPORARY_MANAGER_HXX__
+
+#include <map>
+#include <stack>
+#include <unordered_map>
+
+#include "TIType.hxx"
+#include "TypeLocal.hxx"
+
+#include "dynlib_ast.h"
+
+namespace analysis
+{
+
+    class EXTERN_AST TemporaryManager
+    {
+
+       int currentId;
+       std::map<TypeLocal, std::stack<int>> availableTmp;
+       std::unordered_map<int, TypeLocal> usedTmp;
+
+    public:
+
+       TemporaryManager() : currentId(0) { }
+
+       int getTmp(const TIType & type, const bool isAnInt = false)
+       {
+           TypeLocal tl = TypeLocal::get(type, isAnInt);
+           if (availableTmp.empty())
+           {
+               usedTmp.emplace(currentId, tl);
+               return currentId++;
+           }
+           else
+           {
+               auto i = availableTmp.find(tl);
+               if (i == availableTmp.end())
+               {
+                   usedTmp.emplace(currentId, tl);
+                   return currentId++;
+               }
+               else
+               {
+                   const int id = i->second.top();
+                   i->second.pop();
+                   if (i->second.empty())
+                   {
+                       availableTmp.erase(i);
+                   }
+                   usedTmp.emplace(id, tl);
+
+                   return id;
+               }
+           }
+       }
+
+       void releaseTmp(const int id)
+       {
+           if (id >= 0)
+           {
+               const TypeLocal & tl = usedTmp.find(id)->second;
+               auto i = availableTmp.find(tl);
+               if (i == availableTmp.end())
+               {
+                   i = availableTmp.emplace(tl, std::stack<int>()).first;
+               }
+               i->second.push(id);
+           }
+       }
+
+       inline const std::map<TypeLocal, std::stack<int>> & getTemp() const
+       {
+           return availableTmp;
+       }
+    };
+
+} // namespace analysis
+
+#endif // __TEMPORARY_MANAGER_HXX__
diff --git a/scilab/modules/ast/includes/analysis/data/TypeLocal.hxx b/scilab/modules/ast/includes/analysis/data/TypeLocal.hxx
new file mode 100644 (file)
index 0000000..6cb6c1f
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *  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 __TYPE_LOCAL_HXX__
+#define __TYPE_LOCAL_HXX__
+
+#include <iostream>
+
+#include "TIType.hxx"
+
+namespace analysis
+{
+
+    struct TypeLocal
+    {
+        TIType::Type type;
+        int rows;
+        int cols;
+        bool isAnInt;
+
+        TypeLocal(const TIType::Type _type, const int _rows, const int _cols, const bool _isAnInt) : type(_type), rows(_rows), cols(_cols), isAnInt(_isAnInt) { }
+
+       TypeLocal(const TypeLocal & tl) : type(tl.type), rows(tl.rows), cols(tl.cols), isAnInt(tl.isAnInt) { } 
+       
+        inline bool operator<(const TypeLocal & R) const
+            {
+                return type < R.type || (type == R.type && (rows < R.rows || (rows == R.rows && (cols < R.cols || (cols == R.cols && (int)isAnInt < (int)R.isAnInt)))));
+            }
+
+       inline bool operator==(const TypeLocal & R) const
+            {
+                return type == R.type && rows == R.rows && cols == R.cols && isAnInt == R.isAnInt;
+            }
+
+        inline bool isScalar() const
+            {
+                return rows == 1 && cols == 1;
+            }
+
+       inline bool isKnown() const
+            {
+                return rows != -1;
+            }
+
+       inline int totalSize() const
+            {
+                return isKnown() ? (rows * cols) : -1;
+            }
+
+       inline static TypeLocal get(const TIType & type, const bool isAnInt = false)
+           {
+               if (type.isConstantDims())
+               {
+                   return TypeLocal(type.type, type.rows.getConstant(), type.cols.getConstant(), isAnInt);
+               }
+               else
+               {
+                   return TypeLocal(type.type, -1, -1, false);
+               }       
+           }
+
+        friend std::wostream & operator<<(std::wostream & out, const TypeLocal & tl)
+            {
+                out << TIType::toString(tl.type);
+                if (tl.isAnInt)
+                {
+                    out << L"(int64_t)";
+                }
+                out << L" ";
+                if (tl.rows == -1 || tl.cols == -1)
+                {
+                    out << L"?x?";
+                }
+                else
+                {
+                    out << tl.rows << L'x' << tl.cols;
+                }
+                return out;
+            }
+    };
+
+} // namespace analysis
+
+#endif // __TYPE_LOCAL_HXX__
index 2b5f982..81b82ff 100644 (file)
@@ -49,10 +49,10 @@ public:
      */
     struct Value
     {
-        unsigned long long value;
+        uint64_t value;
         const MultivariatePolynomial * poly;
 
-        Value(const unsigned long long _value) : value(_value), poly(nullptr) { }
+        Value(const uint64_t _value) : value(_value), poly(nullptr) { }
 
         friend inline std::wostream & operator<<(std::wostream & out, const Value & v)
         {
@@ -83,18 +83,18 @@ public:
 private:
 
     typedef std::unordered_map<OpValue, Value, OpValue::Hash, OpValue::Eq> MapValues;
-    typedef std::unordered_map<double, Value> MapDoubles;
+    typedef std::unordered_map<int64_t, Value> MapInt64;
     typedef std::multimap<symbol::Symbol, Value> MapSymbols;
     typedef std::unordered_map<MultivariatePolynomial, Value *, MultivariatePolynomial::Hash, MultivariatePolynomial::Eq> MapPolys;
     typedef std::list<Value> ListValues;
 
     MapValues mapv;
-    MapDoubles mapd;
+    MapInt64 mapi64;
     MapSymbols maps;
     MapPolys mapp;
     ListValues list;
 
-    unsigned long long current;
+    uint64_t current;
 
 public:
 
@@ -113,14 +113,14 @@ public:
     inline void clear()
     {
         mapv.clear();
-        mapd.clear();
+        mapi64.clear();
         maps.clear();
         mapp.clear();
         list.clear();
         current = 0;
     }
 
-    inline unsigned long long getCurrentValue() const
+    inline uint64_t getCurrentValue() const
        {
            return current;
        }
@@ -160,9 +160,9 @@ public:
         {
             Value & value = maps.emplace(sym, current++)->second;
             insertValue(mp, value);
-            if (mp.isConstant() && mapd.find(mp.constant) == mapd.end())
+            if (mp.isConstant() && mapi64.find(mp.constant) == mapi64.end())
             {
-                mapd.emplace(mp.constant, value);
+                mapi64.emplace(mp.constant, value);
             }
         }
     }
@@ -257,18 +257,24 @@ public:
      */
     inline Value * getValue(const double x)
     {
-        const auto i = mapd.find(x);
-        if (i == mapd.end())
-        {
-            Value & value = mapd.emplace(x, current++).first->second;
-            insertValue(x, value);
+       int64_t _x;
+       if (tools::asInteger(x, _x))
+       {
+           const auto i = mapi64.find(_x);
+           if (i == mapi64.end())
+           {
+               Value & value = mapi64.emplace(_x, current++).first->second;
+               insertValue(_x, value);
+               
+               return &value;
+           }
+           else
+           {
+               return &i->second;
+           }
+       }
 
-            return &value;
-        }
-        else
-        {
-            return &i->second;
-        }
+       return nullptr;
     }
 
     /**
@@ -349,9 +355,9 @@ public:
      * \brief Get a map containing association between symbol names and value (as ULL)
      * \return a map
      */
-    inline std::map<std::wstring, unsigned long long> getSymMap() const
+    inline std::map<std::wstring, uint64_t> getSymMap() const
     {
-        std::map<std::wstring, unsigned long long> map;
+        std::map<std::wstring, uint64_t> map;
         for (const auto & p : maps)
         {
             map.emplace(p.first.getName(), p.second.value);
@@ -366,7 +372,7 @@ public:
     friend inline std::wostream & operator<<(std::wostream & out, const GVN & gvn)
     {
         out << L"Constants:" << std::endl;
-        for (const auto & p : gvn.mapd)
+        for (const auto & p : gvn.mapi64)
         {
             out << L"  " << p.first << L" -> " << p.second.value << std::endl;
         }
@@ -377,7 +383,7 @@ public:
             out << L"  " << p.first << L" -> " << p.second.value << std::endl;
         }
 
-        std::map<unsigned long long, std::wstring> map;
+        std::map<uint64_t, std::wstring> map;
         for (const auto & p : gvn.maps)
         {
             map.emplace(p.second.value, p.first.getName());
@@ -396,7 +402,7 @@ public:
         tools::printMapInfo(out, gvn.mapp, show_collisions);
 
         out << std::endl << L"Map constants stats:" << std::endl;
-        tools::printMapInfo(out, gvn.mapd, show_collisions);
+        tools::printMapInfo(out, gvn.mapi64, show_collisions);
 
         out << std::endl << L"Map values stats:" << std::endl;
         tools::printMapInfo(out, gvn.mapv, show_collisions);*/
index c898df3..8c36fda 100644 (file)
@@ -132,7 +132,7 @@ struct MPolyConstraint : public InferenceConstraint
 
     MPolyConstraint(const MultivariatePolynomial & _poly, const Kind _kind) : poly(_poly), kind(_kind)
     {
-        double common;
+        int64_t common;
         if (poly.getCommonCoeff(common) && common != 1 && common != 0)
         {
             if (kind == EQ0)
index ed05a59..73d5ec0 100644 (file)
@@ -37,14 +37,14 @@ struct MultivariateMonomial
 
     // Since the coeff is not used to compute the hash we must set is as mutable to be able to modify it when extract
     // from an unordered_set or unordered_map.
-    mutable double coeff;
+    mutable int64_t coeff;
     Monomial monomial;
 
     /**
      * \brief constructor
      * \param var the default var to put in the monomial
      */
-    MultivariateMonomial(const unsigned long long var) : coeff(1)
+    MultivariateMonomial(const uint64_t var) : coeff(1)
     {
         monomial.emplace(var);
     }
@@ -53,7 +53,7 @@ struct MultivariateMonomial
      * \brief constructor
      * \param coeff the default coefficient for this empty monomial
      */
-    MultivariateMonomial(const double _coeff = 1) : coeff(_coeff) { }
+    MultivariateMonomial(const int64_t _coeff = 1) : coeff(_coeff) { }
 
     /**
      * \brief copy-constructor
@@ -66,7 +66,7 @@ struct MultivariateMonomial
      * \param var an id
      * \return true if the monomial contains the var
      */
-    inline bool contains(const unsigned long long var) const
+    inline bool contains(const uint64_t var) const
        {
            return monomial.find(var) != monomial.end();
        }
@@ -76,7 +76,7 @@ struct MultivariateMonomial
      * \param max an id
      * \return true if all the variables have an id leq to max
      */
-    inline bool checkVariable(const unsigned long long max) const
+    inline bool checkVariable(const uint64_t max) const
     {
        return std::prev(monomial.end())->var <= max;
     }
@@ -163,17 +163,17 @@ struct MultivariateMonomial
     }
 
     /**
-     * \brief Product by a double
+     * \brief Product by a int64_t
      */
-    friend inline MultivariateMonomial operator*(const double L, const MultivariateMonomial & R)
+    friend inline MultivariateMonomial operator*(const int64_t L, const MultivariateMonomial & R)
     {
         return R * L;
     }
 
     /**
-     * \brief Product by a double
+     * \brief Product by a int64_t
      */
-    inline MultivariateMonomial operator*(const double R) const
+    inline MultivariateMonomial operator*(const int64_t R) const
     {
         MultivariateMonomial res(*this);
         res.coeff *= R;
@@ -181,18 +181,18 @@ struct MultivariateMonomial
     }
 
     /**
-     * \brief Product-assignment by a double
+     * \brief Product-assignment by a int64_t
      */
-    inline MultivariateMonomial & operator*=(const double R)
+    inline MultivariateMonomial & operator*=(const int64_t R)
     {
         coeff *= R;
         return *this;
     }
 
     /**
-     * \brief Division by a double
+     * \brief Division by a int64_t
      */
-    inline MultivariateMonomial operator/(const double R) const
+    inline MultivariateMonomial operator/(const int64_t R) const
     {
         MultivariateMonomial res(*this);
         res.coeff /= R;
@@ -200,9 +200,9 @@ struct MultivariateMonomial
     }
 
     /**
-     * \brief Division-assignment by a double
+     * \brief Division-assignment by a int64_t
      */
-    inline MultivariateMonomial & operator/=(const double R)
+    inline MultivariateMonomial & operator/=(const int64_t R)
     {
         coeff /= R;
         return *this;
@@ -238,7 +238,7 @@ struct MultivariateMonomial
      * \param vars a map containing var id -> string representation
      * \return the printed monomial
      */
-    inline const std::wstring print(const std::map<unsigned long long, std::wstring> & vars) const
+    inline const std::wstring print(const std::map<uint64_t, std::wstring> & vars) const
     {
         std::wostringstream wos;
         wos << coeff;
@@ -276,7 +276,7 @@ struct MultivariateMonomial
             std::size_t h = 0;
             for (const auto & ve : m.monomial)
             {
-                h = tools::hash_combine(h, std::hash<unsigned long long>()(ve.var), std::hash<unsigned int>()(ve.exp));
+                h = tools::hash_combine(h, std::hash<uint64_t>()(ve.var), std::hash<unsigned int>()(ve.exp));
             }
             return h;
         }
index a7f3fe8..fbaa12f 100644 (file)
@@ -36,14 +36,15 @@ namespace analysis
 struct MultivariatePolynomial
 {
     typedef std::unordered_set<MultivariateMonomial, MultivariateMonomial::Hash, MultivariateMonomial::Eq> Polynomial;
-    double constant;
+    int64_t constant;
+    bool valid;
     Polynomial polynomial;
 
     /**
      * \brief constructor
      * \param var to init polynomial
      */
-    MultivariatePolynomial(const unsigned long long var) : constant(0)
+    MultivariatePolynomial(const uint64_t var) : constant(0), valid(true)
     {
         polynomial.emplace(var);
     }
@@ -52,19 +53,19 @@ struct MultivariatePolynomial
      * \brief constructor
      * \param _constant to init polynomial
      */
-    MultivariatePolynomial(const double _constant = 0) : constant(_constant) { }
+    MultivariatePolynomial(const int64_t _constant = 0, const bool _valid = true) : constant(_constant), valid(_valid) { }
 
     /**
      * \brief constructor
      * \param _size the size of the polynomial (used to reserve the unordered_set)
      * \param _constant to init polynomial
      */
-    MultivariatePolynomial(const unsigned int _size, const double _constant) : constant(_constant), polynomial(_size) { }
+    MultivariatePolynomial(const unsigned int _size, const int64_t _constant) : constant(_constant), polynomial(_size), valid(true) { }
 
     /**
      * \brief copy constructor
      */
-    MultivariatePolynomial(const MultivariatePolynomial & mp) : constant(mp.constant), polynomial(mp.polynomial) { }
+    MultivariatePolynomial(const MultivariatePolynomial & mp) : constant(mp.constant), polynomial(mp.polynomial), valid(mp.valid) { }
 
     /**
      * \brief Get an invalid polynomial (i.e. constant == NaN)
@@ -72,7 +73,7 @@ struct MultivariatePolynomial
      */
     inline static MultivariatePolynomial getInvalid()
     {
-        return MultivariatePolynomial(tools::NaN());
+        return MultivariatePolynomial(0, false);
     }
 
     /**
@@ -81,7 +82,7 @@ struct MultivariatePolynomial
      */
     inline bool isValid() const
     {
-        return !tools::isNaN(constant);
+        return valid;
     }
 
     /**
@@ -90,7 +91,7 @@ struct MultivariatePolynomial
      */
     inline bool isInvalid() const
     {
-        return tools::isNaN(constant);
+        return !valid;
     }
 
     /**
@@ -98,7 +99,8 @@ struct MultivariatePolynomial
      */
     inline void invalid()
     {
-        constant = tools::NaN();
+        constant = 0;
+       valid = false;
         polynomial.clear();
     }
 
@@ -107,7 +109,7 @@ struct MultivariatePolynomial
      * \param var an id
      * \return true if the polynomial contains the var
      */
-    inline bool contains(const unsigned long long var) const
+    inline bool contains(const uint64_t var) const
        {
            for (const auto & m : polynomial)
            {
@@ -125,7 +127,7 @@ struct MultivariatePolynomial
      * \param max an id
      * \return true if all the variables have an id leq to max
      */
-    inline bool checkVariable(const unsigned long long max) const
+    inline bool checkVariable(const uint64_t max) const
     {
         for (const auto & m : polynomial)
         {
@@ -142,7 +144,7 @@ struct MultivariatePolynomial
      * \param min an id
      * \return true if the polynomial contains a var with an id geq than min
      */
-    inline bool containsVarsGEq(const unsigned long long min) const
+    inline bool containsVarsGEq(const uint64_t min) const
     {
         for (const auto & m : polynomial)
         {
@@ -160,7 +162,7 @@ struct MultivariatePolynomial
      * \param min an id
      * \return a translated polynomial
      */
-    inline MultivariatePolynomial translateVariables(const unsigned long long t, const unsigned long long min) const
+    inline MultivariatePolynomial translateVariables(const uint64_t t, const uint64_t min) const
     {
        MultivariatePolynomial mp;
         for (const auto & m : polynomial)
@@ -188,9 +190,9 @@ struct MultivariatePolynomial
      * \param coeff the multiplcative coefficient to applicate to the monomial
      * \return *this
      */
-    inline MultivariatePolynomial & add(const MultivariateMonomial & m, const double coeff = 1)
+    inline MultivariatePolynomial & add(const MultivariateMonomial & m, const int64_t coeff = 1)
     {
-        const double c = m.coeff * coeff;
+        const int64_t c = m.coeff * coeff;
         if (c)
         {
             Polynomial::iterator i = polynomial.find(m);
@@ -270,7 +272,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the + operator
      */
-    inline MultivariatePolynomial operator+(const double R) const
+    inline MultivariatePolynomial operator+(const int64_t R) const
     {
         if (isValid())
         {
@@ -284,7 +286,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the += operator
      */
-    inline MultivariatePolynomial & operator+=(const double R)
+    inline MultivariatePolynomial & operator+=(const int64_t R)
     {
         if (isValid())
         {
@@ -322,7 +324,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the - operator
      */
-    inline MultivariatePolynomial operator-(const double R) const
+    inline MultivariatePolynomial operator-(const int64_t R) const
     {
         if (isValid())
         {
@@ -354,7 +356,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the -= operator
      */
-    inline MultivariatePolynomial & operator-=(const double R)
+    inline MultivariatePolynomial & operator-=(const int64_t R)
     {
         if (isValid())
         {
@@ -563,7 +565,7 @@ struct MultivariatePolynomial
     {
         if (isValid())
         {
-            MultivariatePolynomial res(static_cast<unsigned int>(polynomial.size() + 1), 0.);
+            MultivariatePolynomial res(static_cast<unsigned int>(polynomial.size() + 1), int64_t(0));
             res.add(constant * R);
             for (const auto & mL : polynomial)
             {
@@ -594,7 +596,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the * operator
      */
-    inline MultivariatePolynomial operator*(const double R) const
+    inline MultivariatePolynomial operator*(const int64_t R) const
     {
         if (isValid())
         {
@@ -617,7 +619,7 @@ struct MultivariatePolynomial
             }
             else
             {
-                return MultivariatePolynomial(0.);
+                return MultivariatePolynomial(int64_t(0));
             }
         }
         return getInvalid();
@@ -626,13 +628,13 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the *= operator
      */
-    inline MultivariatePolynomial & operator*=(const double R)
+    inline MultivariatePolynomial & operator*=(const int64_t R)
     {
         if (isValid())
         {
             if (R == 0)
             {
-                constant = 0.;
+                constant = 0;
                 polynomial.clear();
             }
             else if (R != 1)
@@ -650,7 +652,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the / operator
      */
-    inline MultivariatePolynomial operator/(const double R) const
+    inline MultivariatePolynomial operator/(const int64_t R) const
     {
         if (isValid())
         {
@@ -671,7 +673,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of the /= operator
      */
-    inline MultivariatePolynomial & operator/=(const double R)
+    inline MultivariatePolynomial & operator/=(const int64_t R)
     {
         if (isValid())
         {
@@ -696,7 +698,7 @@ struct MultivariatePolynomial
         {
             if (R == 0)
             {
-                return MultivariatePolynomial(1.);
+                return MultivariatePolynomial(int64_t(1));
             }
             else if (R == 1)
             {
@@ -708,7 +710,7 @@ struct MultivariatePolynomial
                 {
                     if (polynomial.empty())
                     {
-                        return MultivariatePolynomial(0.);
+                        return MultivariatePolynomial(int64_t(0));
                     }
                     else if (polynomial.size() == 1)
                     {
@@ -722,11 +724,11 @@ struct MultivariatePolynomial
 
                 if (polynomial.empty())
                 {
-                    return MultivariatePolynomial(std::pow(constant, R));
+                    return MultivariatePolynomial(tools::powui(constant, R));
                 }
 
                 MultivariatePolynomial p = *this;
-                MultivariatePolynomial y = (R & 1) ? *this : MultivariatePolynomial(1.);
+                MultivariatePolynomial y = (R & 1) ? *this : MultivariatePolynomial(int64_t(1));
 
                 while (R >>= 1)
                 {
@@ -776,7 +778,7 @@ struct MultivariatePolynomial
             return getInvalid();
         }
 
-        std::unordered_map<unsigned long long, std::set<unsigned int>> expected_exps;
+        std::unordered_map<uint64_t, std::set<unsigned int>> expected_exps;
         for (const auto & m : polynomial)
         {
             for (const auto & ve : m.monomial)
@@ -788,7 +790,7 @@ struct MultivariatePolynomial
             }
         }
 
-        std::unordered_map<unsigned long long, std::unordered_map<unsigned int, MultivariatePolynomial>> exps;
+        std::unordered_map<uint64_t, std::unordered_map<unsigned int, MultivariatePolynomial>> exps;
         for (const auto & p : expected_exps)
         {
             if (p.second.size() == 1)
@@ -861,7 +863,7 @@ struct MultivariatePolynomial
                 }
                 else
                 {
-                    MultivariateMonomial mm(1.);
+                    MultivariateMonomial mm(int64_t(1));
                     r *= mm.add(ve);
                 }
             }
@@ -872,6 +874,41 @@ struct MultivariatePolynomial
     }
 
     /**
+     * \brief Check divisibility by an integer
+     * \return true if all the coeffs are divisible by n
+     */
+    inline bool isDivisibleBy(const int64_t n) const
+    {
+        if (constant % n == 0)
+        {
+            for (const auto & m : polynomial)
+            {
+                if (m.coeff % n != 0)
+                {
+                   return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * \brief Check divisibility by a polynomial
+     * For now the polynomial must be constant.
+     * \return true if this is divisible by mp
+     */
+    inline bool isDivisibleBy(const MultivariatePolynomial & mp) const
+    {
+       if (mp.polynomial.empty())
+       {
+           return isDivisibleBy(mp.constant);
+       }
+
+       return false;
+    }
+    
+    /**
      * \brief Check positivity
      * \return true if all the coeffs are positive and the exponents are even
      */
@@ -990,7 +1027,7 @@ struct MultivariatePolynomial
      * \param vars a mapping between vars numbers and wstring representation
      * \return a wstring representing this polynomial
      */
-    inline const std::wstring print(const std::map<unsigned long long, std::wstring> & vars) const
+    inline const std::wstring print(const std::map<uint64_t, std::wstring> & vars) const
     {
         std::wostringstream wos;
         wos << constant;
@@ -1007,7 +1044,7 @@ struct MultivariatePolynomial
      */
     friend inline std::wostream & operator<<(std::wostream & out, const MultivariatePolynomial & p)
     {
-        const std::map<unsigned long long, std::wstring> vars;
+        const std::map<uint64_t, std::wstring> vars;
         out << p.constant;
         std::set<MultivariateMonomial, MultivariateMonomial::Compare> s(p.polynomial.begin(), p.polynomial.end());
         for (const auto & m : s)
@@ -1038,7 +1075,7 @@ struct MultivariatePolynomial
      * \param val the constant value to check
      * \return true if the polynomial is constant and equal to val
      */
-    inline bool isConstant(const double val) const
+    inline bool isConstant(const int64_t val) const
     {
         return isConstant() && constant == val;
     }
@@ -1048,7 +1085,7 @@ struct MultivariatePolynomial
      * \param[out] common the common value
      * \return true if there is a common coeff
      */
-    inline bool getCommonCoeff(double & common) const
+    inline bool getCommonCoeff(int64_t & common) const
     {
         if (constant != 0)
         {
@@ -1090,7 +1127,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of == operator
      */
-    inline bool operator==(const double R) const
+    inline bool operator==(const int64_t R) const
     {
         return polynomial.empty() && constant == R;
     }
@@ -1098,7 +1135,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of != operator
      */
-    inline bool operator!=(const double R) const
+    inline bool operator!=(const int64_t R) const
     {
         return !(*this == R);
     }
@@ -1106,7 +1143,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of == operator
      */
-    friend inline bool operator==(const double L, const MultivariatePolynomial & R)
+    friend inline bool operator==(const int64_t L, const MultivariatePolynomial & R)
     {
         return R == L;
     }
@@ -1114,7 +1151,7 @@ struct MultivariatePolynomial
     /**
      * \brief Overload of != operator
      */
-    friend inline bool operator!=(const double L, const MultivariatePolynomial & R)
+    friend inline bool operator!=(const int64_t L, const MultivariatePolynomial & R)
     {
         return R != L;
     }
@@ -1124,12 +1161,12 @@ struct MultivariatePolynomial
      */
     inline std::size_t hash() const
     {
-        std::size_t h = std::hash<double>()(constant);
+        std::size_t h = std::hash<int64_t>()(constant);
         for (const auto & m : polynomial)
         {
             // since the order of the monomials is not always the same
             // we must use a commutative operation to combine the monomial's hashes
-            h += tools::hash_combine(std::hash<double>()(m.coeff), MultivariateMonomial::Hash()(m));
+            h += tools::hash_combine(std::hash<int64_t>()(m.coeff), MultivariateMonomial::Hash()(m));
         }
 
         return h;
@@ -1162,7 +1199,7 @@ struct MultivariatePolynomial
 private:
 
     // Helper function to use with eval
-    inline static bool __isValid(const std::unordered_map<unsigned long long, const MultivariatePolynomial *> & values)
+    inline static bool __isValid(const std::unordered_map<uint64_t, const MultivariatePolynomial *> & values)
     {
         for (const auto & p : values)
         {
@@ -1188,31 +1225,31 @@ private:
     }
 
     // Helper function to use with eval
-    inline static bool __isValid(const std::pair<unsigned long long, const MultivariatePolynomial *> & values)
+    inline static bool __isValid(const std::pair<uint64_t, const MultivariatePolynomial *> & values)
     {
        return values.second->isValid();
     }
 
     // Helper function to use with eval
-    inline static bool __contains(const std::unordered_map<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static bool __contains(const std::unordered_map<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
         return values.find(val) != values.end();
     }
 
     // Helper function to use with eval
-    inline static bool __contains(const std::vector<const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static bool __contains(const std::vector<const MultivariatePolynomial *> & values, const uint64_t val)
     {
         return val < values.size();
     }
 
     // Helper function to use with eval
-    inline static bool __contains(const std::pair<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static bool __contains(const std::pair<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
         return values.first == val;
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __get(const std::unordered_map<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __get(const std::unordered_map<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
         const auto i = values.find(val);
         if (i != values.end())
@@ -1223,13 +1260,13 @@ private:
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __getSafe(const std::unordered_map<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __getSafe(const std::unordered_map<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
        return values.find(val)->second;
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __get(const std::vector<const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __get(const std::vector<const MultivariatePolynomial *> & values, const uint64_t val)
     {
        if (val < values.size())
        {
@@ -1239,13 +1276,13 @@ private:
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __getSafe(const std::vector<const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __getSafe(const std::vector<const MultivariatePolynomial *> & values, const uint64_t val)
     {
         return values[val];
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __get(const std::pair<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __get(const std::pair<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
        if (values.first == val)
        {
@@ -1255,7 +1292,7 @@ private:
     }
 
     // Helper function to use with eval
-    inline static const MultivariatePolynomial * __getSafe(const std::pair<unsigned long long, const MultivariatePolynomial *> & values, const unsigned long long val)
+    inline static const MultivariatePolynomial * __getSafe(const std::pair<uint64_t, const MultivariatePolynomial *> & values, const uint64_t val)
     {
        return values.second;
     }
index 5112f0f..25bbd0f 100644 (file)
@@ -26,20 +26,20 @@ namespace analysis
  */
 struct OpValue
 {
-    enum Kind : unsigned char
+    enum Kind : uint8_t
     {
         UNARYMINUS = 0, UNARYNEG, PLUS, MINUS, TIMES, DOTTIMES, RDIV, DOTRDIV, POWER, DOTPOWER
     };
     const Kind kind;
-    unsigned long long lnum : 60;
-    unsigned long long rnum : 60;
+    uint64_t lnum : 60;
+    uint64_t rnum : 60;
 
     /**
      * \brief constructor for unary operation
      * \param _kind the operation kind
      * \param _lnum the value of the operand
      */
-    OpValue(Kind _kind, unsigned long long _lnum) : kind(_kind), lnum(_lnum) { }
+    OpValue(Kind _kind, uint64_t _lnum) : kind(_kind), lnum(_lnum) { }
 
     /**
      * \brief constructor for binary operation
@@ -47,11 +47,11 @@ struct OpValue
      * \param _lnum the value of the left operand
      * \param _rnum the value of the right operand
      */
-    OpValue(Kind _kind, unsigned long long _lnum, unsigned long long _rnum) : kind(_kind), lnum(_lnum), rnum(_rnum)
+    OpValue(Kind _kind, uint64_t _lnum, uint64_t _rnum) : kind(_kind), lnum(_lnum), rnum(_rnum)
     {
         if (isCommutative() && lnum > rnum)
         {
-            const unsigned long long x = lnum;
+            const uint64_t x = lnum;
             lnum = rnum;
             rnum = x;
         }
index 2638536..2effa11 100644 (file)
@@ -62,7 +62,7 @@ public:
      * \param _gvn the GVN associated with this dimension
      * \param dim the value of this dimension
      */
-    SymbolicDimension(GVN & _gvn, double dim) : gvn(&_gvn), value(dim == -1 ? _gvn.getValue() : _gvn.getValue(dim)) { }
+    SymbolicDimension(GVN & _gvn, int64_t dim) : gvn(&_gvn), value(dim == -1 ? _gvn.getValue() : _gvn.getValue(dim)) { }
 
     /**
      * \brief Get the associated GVN
@@ -104,7 +104,7 @@ public:
      * \brief Get the constant part of the associated polynomial
      * \return the constant
      */
-    inline double getConstant() const
+    inline int64_t getConstant() const
     {
         return value->poly->constant;
     }
@@ -149,7 +149,7 @@ public:
      * \brief Set the associated Value
      * \param _value a Value
      */
-    inline void setValue(const double _value)
+    inline void setValue(const int64_t _value)
     {
         value = gvn->getValue(_value);
     }
@@ -204,7 +204,7 @@ public:
     /**
      * \brief Overload of the + operator
      */
-    inline SymbolicDimension operator+(const double R) const
+    inline SymbolicDimension operator+(const int64_t R) const
     {
         return SymbolicDimension(gvn, gvn->getValue(OpValue::Kind::PLUS, *value, *gvn->getValue(R)));
     }
@@ -220,7 +220,7 @@ public:
     /**
      * \brief Overload of the - operator
      */
-    inline SymbolicDimension operator-(const double R) const
+    inline SymbolicDimension operator-(const int64_t R) const
     {
         return SymbolicDimension(gvn, gvn->getValue(OpValue::Kind::MINUS, *value, *gvn->getValue(R)));
     }
@@ -236,7 +236,7 @@ public:
     /**
      * \brief Overload of the * operator
      */
-    inline SymbolicDimension operator*(const double R) const
+    inline SymbolicDimension operator*(const int64_t R) const
     {
         return SymbolicDimension(gvn, gvn->getValue(OpValue::Kind::TIMES, *value, *gvn->getValue(R)));
     }
@@ -268,7 +268,7 @@ public:
     /**
      * \brief Overload of the / operator
      */
-    inline SymbolicDimension operator/(const double R) const
+    inline SymbolicDimension operator/(const int64_t R) const
     {
         return SymbolicDimension(gvn, gvn->getValue(OpValue::Kind::RDIV, *value, *gvn->getValue(R)));
     }
@@ -284,7 +284,7 @@ public:
     /**
      * \brief Overload of the ^ operator
      */
-    inline SymbolicDimension operator^(const double R) const
+    inline SymbolicDimension operator^(const int64_t R) const
     {
         return SymbolicDimension(gvn, gvn->getValue(OpValue::Kind::POWER, *value, *gvn->getValue(R)));
     }
@@ -300,7 +300,7 @@ public:
     /**
      * \brief Overload of the == operator
      */
-    inline bool operator==(const double R) const
+    inline bool operator==(const int64_t R) const
     {
         return value->poly->isConstant(R);
     }
@@ -316,7 +316,7 @@ public:
     /**
      * \brief Overload of the != operator
      */
-    inline bool operator!=(const double R) const
+    inline bool operator!=(const int64_t R) const
     {
         return !value->poly->isConstant(R);
     }
@@ -324,7 +324,7 @@ public:
     /**
      * \brief Overload of the + operator
      */
-    inline friend SymbolicDimension operator+(const double L, const SymbolicDimension & R)
+    inline friend SymbolicDimension operator+(const int64_t L, const SymbolicDimension & R)
     {
         return R + L;
     }
@@ -332,7 +332,7 @@ public:
     /**
      * \brief Overload of the - operator
      */
-    inline friend SymbolicDimension operator-(const double L, const SymbolicDimension & R)
+    inline friend SymbolicDimension operator-(const int64_t L, const SymbolicDimension & R)
     {
         return SymbolicDimension(R.gvn, R.gvn->getValue(OpValue::Kind::MINUS, *R.gvn->getValue(L), *R.value));
     }
@@ -340,7 +340,7 @@ public:
     /**
      * \brief Overload of the * operator
      */
-    inline friend SymbolicDimension operator*(const double L, const SymbolicDimension & R)
+    inline friend SymbolicDimension operator*(const int64_t L, const SymbolicDimension & R)
     {
         return R * L;
     }
@@ -348,7 +348,7 @@ public:
     /**
      * \brief Overload of the / operator
      */
-    inline friend SymbolicDimension operator/(const double L, const SymbolicDimension & R)
+    inline friend SymbolicDimension operator/(const int64_t L, const SymbolicDimension & R)
     {
         return SymbolicDimension(R.gvn, R.gvn->getValue(OpValue::Kind::RDIV, *R.gvn->getValue(L), *R.value));
     }
@@ -356,7 +356,7 @@ public:
     /**
      * \brief Overload of the ^ operator
      */
-    inline friend SymbolicDimension operator^(const double L, const SymbolicDimension & R)
+    inline friend SymbolicDimension operator^(const int64_t L, const SymbolicDimension & R)
     {
         return SymbolicDimension(R.gvn, R.gvn->getValue(OpValue::Kind::POWER, *R.gvn->getValue(L), *R.value));
     }
@@ -364,7 +364,7 @@ public:
     /**
      * \brief Overload of the == operator
      */
-    inline friend bool operator==(const double L, const SymbolicDimension & R)
+    inline friend bool operator==(const int64_t L, const SymbolicDimension & R)
     {
         return R == L;
     }
@@ -372,7 +372,7 @@ public:
     /**
      * \brief Overload of the != operator
      */
-    inline friend bool operator!=(const double L, const SymbolicDimension & R)
+    inline friend bool operator!=(const int64_t L, const SymbolicDimension & R)
     {
         return R != L;
     }
index c77432b..f57d667 100644 (file)
@@ -60,7 +60,7 @@ public:
      * \param _start the starting value
      * \param _end the ending value
      */
-    SymbolicRange(GVN & _gvn, double _start, double _end) : SymbolicRange(&_gvn, _gvn.getValue(_start), _gvn.getValue(_end)) { }
+    SymbolicRange(GVN & _gvn, int64_t _start, int64_t _end) : SymbolicRange(&_gvn, _gvn.getValue(_start), _gvn.getValue(_end)) { }
 
     inline void set(GVN & _gvn, GVN::Value * _start, GVN::Value * _end)
        {
@@ -108,6 +108,16 @@ public:
     }
 
     /**
+     * \brief Overload of the + operator
+     */
+    inline SymbolicRange operator+(const GVN::Value & R) const
+    {
+        return SymbolicRange(gvn,
+                             gvn->getValue(OpValue::Kind::PLUS, *start, R),
+                             gvn->getValue(OpValue::Kind::PLUS, *end, R));
+    }
+
+    /**
      * \brief Overload of the - operator
      */
     inline SymbolicRange operator-(const SymbolicRange & R) const
@@ -118,6 +128,26 @@ public:
     }
 
     /**
+     * \brief Overload of the - operator
+     */
+    inline SymbolicRange operator-(const GVN::Value & R) const
+    {
+        return SymbolicRange(gvn,
+                             gvn->getValue(OpValue::Kind::MINUS, *start, R),
+                             gvn->getValue(OpValue::Kind::MINUS, *end, R));
+    }
+
+    /**
+     * \brief Overload of the - operator
+     */
+    friend inline SymbolicRange operator-(const GVN::Value & L, const SymbolicRange & R)
+    {
+        return SymbolicRange(R.gvn,
+                             R.gvn->getValue(OpValue::Kind::MINUS, L, *R.end),
+                             R.gvn->getValue(OpValue::Kind::MINUS, L, *R.start));
+    }
+
+    /**
      * \brief Overload of the * operator
      */
     inline SymbolicRange operator*(const SymbolicRange & R) const
@@ -129,6 +159,17 @@ public:
     }
 
     /**
+     * \brief Overload of the * operator
+     */
+    inline SymbolicRange operator*(const GVN::Value & R) const
+    {
+        // We suppose that all the values are positive or null
+        return SymbolicRange(gvn,
+                             gvn->getValue(OpValue::Kind::TIMES, *start, R),
+                             gvn->getValue(OpValue::Kind::TIMES, *end, R));
+    }
+
+    /**
      * \brief Overload of the / operator
      */
     inline SymbolicRange operator/(const SymbolicRange & R) const
@@ -140,6 +181,27 @@ public:
     }
 
     /**
+     * \brief Overload of the / operator
+     */
+    inline SymbolicRange operator/(const GVN::Value & R) const
+    {
+        // We suppose that all the values are positive or null
+        return SymbolicRange(gvn,
+                             gvn->getValue(OpValue::Kind::RDIV, *start, R),
+                             gvn->getValue(OpValue::Kind::RDIV, *end, R));
+    }
+
+    /**
+     * \brief Overload of the - operator
+     */
+    friend inline SymbolicRange operator/(const GVN::Value & L, const SymbolicRange & R)
+    {
+        return SymbolicRange(R.gvn,
+                             R.gvn->getValue(OpValue::Kind::RDIV, L, *R.end),
+                             R.gvn->getValue(OpValue::Kind::RDIV, L, *R.start));
+    }
+
+    /**
      * \brief Overload of the == operator
      */
     inline bool operator==(const SymbolicRange & R) const
index 6d6b692..880b3e6 100644 (file)
@@ -61,7 +61,7 @@ public:
         return *_result;
     }
 
-    inline std::map<std::wstring, unsigned long long> getSymMap() const
+    inline std::map<std::wstring, uint64_t> getSymMap() const
     {
         return gvn.getSymMap();
     }
@@ -124,7 +124,7 @@ private:
         const GVN::Value & LV = getResult();
         e.getRight().accept(*this);
         const GVN::Value & RV = getResult();
-
+       
         switch (e.getOper())
         {
             case ast::OpExp::plus:
@@ -191,7 +191,7 @@ private:
             if (e.getRightExp().isCallExp())
             {
                 ast::CallExp & ce = static_cast<ast::CallExp &>(e.getRightExp());
-                std::unordered_map<unsigned long long, const MultivariatePolynomial *> args;
+                std::unordered_map<uint64_t, const MultivariatePolynomial *> args;
                 const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
                 for (auto & arg : ce.getExps())
                 {
index 8b3068a..af22f8a 100644 (file)
@@ -29,7 +29,7 @@ namespace analysis
  */
 struct VarExp
 {
-    unsigned long long var;
+    uint64_t var;
 
     // this field is mutable since it is not used in the hash computation
     // and could me modified.
@@ -40,14 +40,14 @@ struct VarExp
      * \param _var the var number
      * \param _exp the exponent
      */
-    VarExp(unsigned long long _var, unsigned int _exp = 1) : var(_var), exp(_exp) { }
+    VarExp(uint64_t _var, unsigned int _exp = 1) : var(_var), exp(_exp) { }
 
     /**
      * \brief Print this VarExp
      * \param vars a map containing association between var number and wstring
      * \return a wstring containing the representation of this VarExp
      */
-    inline const std::wstring print(const std::map<unsigned long long, std::wstring> & vars) const
+    inline const std::wstring print(const std::map<uint64_t, std::wstring> & vars) const
     {
         std::wostringstream wos;
         const auto i = vars.find(var);
index 009f523..63d1163 100644 (file)
@@ -174,6 +174,24 @@ namespace analysis
             }
         }
 
+       template<typename T>
+       inline static T powui(T x, uint64_t n)
+       {
+           T p = x;
+           T y = (n & 1) ? x : 1;
+           
+           while (n >>= 1)
+           {
+               p *= p;
+               if (n & 1)
+               {
+                   y *= p;
+               }
+           }
+           
+           return y;
+       }
+
         inline std::wostream & operator<<(std::wostream & out, const IntType & it)
         {
             switch (it)
index 8e68c6d..bd764c7 100644 (file)
@@ -27,7 +27,7 @@ namespace ast
 class EXTERN_AST DebugVisitor : public GenVisitor<const_kind>
 {
 public:
-    DebugVisitor() {}
+    DebugVisitor(std::wostream & my_ostr = std::wcerr) : ostr(&my_ostr) { }
 
     /** \name Visit Matrix Expressions nodes.
      ** \{ */
@@ -143,6 +143,16 @@ public:
             }
         }
     }
+
+protected:
+    std::wostream * ostr;
+
+private:
+    
+    void DEBUG_START_NODE(const ast::Ast & e);
+    void DEBUG_END_NODE(void);
+    void DEBUG(wstring str);
+    void DEBUG(wstring str, const Exp & e);
 };
 }
 #endif // !AST_DEBUGVISITOR_HXX
index ed8ef15..41156dc 100644 (file)
@@ -34,79 +34,79 @@ namespace analysis
 {
     AnalysisVisitor::MapSymCall AnalysisVisitor::symscall = AnalysisVisitor::initCalls();//a=1:3;b=2;c=3;testAnalysis("repmat","a","b","c")
 
-AnalysisVisitor::MapSymCall AnalysisVisitor::initCalls()
-{
-    MapSymCall msc;
-
-    msc.emplace(L"zeros", std::shared_ptr<CallAnalyzer>(new ZerosAnalyzer()));
-    msc.emplace(L"ones", std::shared_ptr<CallAnalyzer>(new OnesAnalyzer()));
-    msc.emplace(L"rand", std::shared_ptr<CallAnalyzer>(new RandAnalyzer()));
-    msc.emplace(L"matrix", std::shared_ptr<CallAnalyzer>(new MatrixAnalyzer()));
-    msc.emplace(L"eye", std::shared_ptr<CallAnalyzer>(new EyeAnalyzer()));
-
-    std::shared_ptr<CallAnalyzer> ca(new CeilAnalyzer());
-    msc.emplace(L"ceil", ca);
-    msc.emplace(L"floor", ca);
-    msc.emplace(L"round", ca);
-    msc.emplace(L"fix", ca);
-    msc.emplace(L"int", ca);
-
-    //msc.emplace(L"sqrt", std::shared_ptr<CallAnalyzer>(new SqrtAnalyzer()));
-    msc.emplace(L"argn", std::shared_ptr<CallAnalyzer>(new ArgnAnalyzer()));
-    msc.emplace(L"size", std::shared_ptr<CallAnalyzer>(new SizeAnalyzer()));
-    msc.emplace(L"length", std::shared_ptr<CallAnalyzer>(new LengthAnalyzer()));
-    msc.emplace(L"diag", std::shared_ptr<CallAnalyzer>(new DiagAnalyzer()));
-    msc.emplace(L"type", std::shared_ptr<CallAnalyzer>(new TypeAnalyzer()));
-    msc.emplace(L"typeof", std::shared_ptr<CallAnalyzer>(new TypeofAnalyzer()));
-    msc.emplace(L"inttype", std::shared_ptr<CallAnalyzer>(new InttypeAnalyzer()));
-    msc.emplace(L"iconvert", std::shared_ptr<CallAnalyzer>(new IconvertAnalyzer()));
-    msc.emplace(L"isreal", std::shared_ptr<CallAnalyzer>(new IsrealAnalyzer()));
-    msc.emplace(L"isscalar", std::shared_ptr<CallAnalyzer>(new IsscalarAnalyzer()));
-    msc.emplace(L"find", std::shared_ptr<CallAnalyzer>(new FindAnalyzer()));
-
-    return msc;
-}
-
-    bool AnalysisVisitor::asDouble(types::InternalType * pIT, double & out)
+    AnalysisVisitor::MapSymCall AnalysisVisitor::initCalls()
     {
-       if (pIT && pIT->isDouble())
-       {
-           types::Double * pDbl = static_cast<types::Double *>(pIT);
-           if (!pDbl->isComplex() && pDbl->getSize() == 1)
-           {
-               out = pDbl->get()[0];
-               return true;
-           }
-       }
+        MapSymCall msc;
 
-       return false;
-    }
-    
-bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
-{
-    if (e.isDoubleExp())
-    {
-        out = static_cast<ast::DoubleExp &>(e).getValue();
-        return true;
+        msc.emplace(L"zeros", std::shared_ptr<CallAnalyzer>(new ZerosAnalyzer()));
+        msc.emplace(L"ones", std::shared_ptr<CallAnalyzer>(new OnesAnalyzer()));
+        msc.emplace(L"rand", std::shared_ptr<CallAnalyzer>(new RandAnalyzer()));
+        msc.emplace(L"matrix", std::shared_ptr<CallAnalyzer>(new MatrixAnalyzer()));
+        msc.emplace(L"eye", std::shared_ptr<CallAnalyzer>(new EyeAnalyzer()));
+
+        std::shared_ptr<CallAnalyzer> ca(new CeilAnalyzer());
+        msc.emplace(L"ceil", ca);
+        msc.emplace(L"floor", ca);
+        msc.emplace(L"round", ca);
+        msc.emplace(L"fix", ca);
+        msc.emplace(L"int", ca);
+
+        //msc.emplace(L"sqrt", std::shared_ptr<CallAnalyzer>(new SqrtAnalyzer()));
+        msc.emplace(L"argn", std::shared_ptr<CallAnalyzer>(new ArgnAnalyzer()));
+        msc.emplace(L"size", std::shared_ptr<CallAnalyzer>(new SizeAnalyzer()));
+        msc.emplace(L"length", std::shared_ptr<CallAnalyzer>(new LengthAnalyzer()));
+        msc.emplace(L"diag", std::shared_ptr<CallAnalyzer>(new DiagAnalyzer()));
+        msc.emplace(L"type", std::shared_ptr<CallAnalyzer>(new TypeAnalyzer()));
+        msc.emplace(L"typeof", std::shared_ptr<CallAnalyzer>(new TypeofAnalyzer()));
+        msc.emplace(L"inttype", std::shared_ptr<CallAnalyzer>(new InttypeAnalyzer()));
+        msc.emplace(L"iconvert", std::shared_ptr<CallAnalyzer>(new IconvertAnalyzer()));
+        msc.emplace(L"isreal", std::shared_ptr<CallAnalyzer>(new IsrealAnalyzer()));
+        msc.emplace(L"isscalar", std::shared_ptr<CallAnalyzer>(new IsscalarAnalyzer()));
+        msc.emplace(L"find", std::shared_ptr<CallAnalyzer>(new FindAnalyzer()));
+
+        return msc;
     }
-    else if (e.isOpExp())
+
+    bool AnalysisVisitor::asDouble(types::InternalType * pIT, double & out)
     {
-        ast::OpExp & op = static_cast<ast::OpExp &>(e);
-        if (op.getOper() == ast::OpExp::unaryMinus)
+        if (pIT && pIT->isDouble())
         {
-            if (op.getRight().isDoubleExp())
+            types::Double * pDbl = static_cast<types::Double *>(pIT);
+            if (!pDbl->isComplex() && pDbl->getSize() == 1)
             {
-                out = -static_cast<ast::DoubleExp &>(op.getRight()).getValue();
+                out = pDbl->get()[0];
                 return true;
             }
         }
-        else if (op.getLeft().isDoubleExp() && op.getRight().isDoubleExp())
-        {
-            const double L = static_cast<ast::DoubleExp &>(op.getLeft()).getValue();
-            const double R = static_cast<ast::DoubleExp &>(op.getRight()).getValue();
 
-            switch (op.getOper())
+        return false;
+    }
+
+    bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
+    {
+        if (e.isDoubleExp())
+        {
+            out = static_cast<ast::DoubleExp &>(e).getValue();
+            return true;
+        }
+        else if (e.isOpExp())
+        {
+            ast::OpExp & op = static_cast<ast::OpExp &>(e);
+            if (op.getOper() == ast::OpExp::unaryMinus)
+            {
+                if (op.getRight().isDoubleExp())
+                {
+                    out = -static_cast<ast::DoubleExp &>(op.getRight()).getValue();
+                    return true;
+                }
+            }
+            else if (op.getLeft().isDoubleExp() && op.getRight().isDoubleExp())
             {
+                const double L = static_cast<ast::DoubleExp &>(op.getLeft()).getValue();
+                const double R = static_cast<ast::DoubleExp &>(op.getRight()).getValue();
+
+                switch (op.getOper())
+                {
                 case ast::OpExp::minus:
                     out = L - R;
                     return true;
@@ -134,70 +134,70 @@ bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
                     return true;
                 default:
                     return false;
+                }
             }
         }
-    }
 
-    return false;
-}
-
-bool AnalysisVisitor::isDoubleConstant(const ast::Exp & e)
-{
-    if (e.isDoubleExp())
-    {
-        return true;
+        return false;
     }
-    else if (e.isOpExp())
+
+    bool AnalysisVisitor::isDoubleConstant(const ast::Exp & e)
     {
-        const ast::OpExp & oe = static_cast<const ast::OpExp &>(e);
-        if (!oe.isBooleanOp())
+        if (e.isDoubleExp())
         {
-            return isDoubleConstant(oe.getLeft()) && isDoubleConstant(oe.getRight());
+            return true;
         }
-        return false;
-    }
-    else if (e.isMatrixExp())
-    {
-        const ast::MatrixExp & me = static_cast<const ast::MatrixExp &>(e);
-        const ast::exps_t & lines = me.getLines();
-        for (const auto line : lines)
+        else if (e.isOpExp())
+        {
+            const ast::OpExp & oe = static_cast<const ast::OpExp &>(e);
+            if (!oe.isBooleanOp())
+            {
+                return isDoubleConstant(oe.getLeft()) && isDoubleConstant(oe.getRight());
+            }
+            return false;
+        }
+        else if (e.isMatrixExp())
         {
-            const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
-            for (const auto column : columns)
+            const ast::MatrixExp & me = static_cast<const ast::MatrixExp &>(e);
+            const ast::exps_t & lines = me.getLines();
+            for (const auto line : lines)
             {
-                if (column && !isDoubleConstant(*column))
+                const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
+                for (const auto column : columns)
                 {
-                    return false;
+                    if (column && !isDoubleConstant(*column))
+                    {
+                        return false;
+                    }
                 }
             }
+            return true;
         }
-        return true;
-    }
-    else if (e.isListExp())
-    {
-        const ast::ListExp & le = static_cast<const ast::ListExp &>(e);
-        return isDoubleConstant(le.getStart()) && isDoubleConstant(le.getStep()) && isDoubleConstant(le.getEnd());
-    }
-    else if (e.isSimpleVar())
-    {
-        const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e);
-        const symbol::Symbol & sym = var.getSymbol();
-        const std::wstring & name = sym.getName();
-        return name == L"%i" || name == L"%inf" || name == L"%nan" || name == L"%eps" || name == L"%pi" || name == L"%e";
-    }
-    else if (e.isCallExp())
-    {
-        const ast::CallExp & ce = static_cast<const ast::CallExp &>(e);
-        const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(ce.getName());
-        const std::wstring & name = var.getSymbol().getName();
-
-        // TODO: check if 'ones' and 'zeros' are the expected functions
-        // ie: ones="abc"; ones(1) !!!
-        if (name == L"ones" || name == L"zeros")
+        else if (e.isListExp())
+        {
+            const ast::ListExp & le = static_cast<const ast::ListExp &>(e);
+            return isDoubleConstant(le.getStart()) && isDoubleConstant(le.getStep()) && isDoubleConstant(le.getEnd());
+        }
+        else if (e.isSimpleVar())
+        {
+            const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e);
+            const symbol::Symbol & sym = var.getSymbol();
+            const std::wstring & name = sym.getName();
+            return name == L"%i" || name == L"%inf" || name == L"%nan" || name == L"%eps" || name == L"%pi" || name == L"%e";
+        }
+        else if (e.isCallExp())
         {
-            const ast::exps_t args = ce.getArgs();
-            switch (args.size())
+            const ast::CallExp & ce = static_cast<const ast::CallExp &>(e);
+            const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(ce.getName());
+            const std::wstring & name = var.getSymbol().getName();
+
+            // TODO: check if 'ones' and 'zeros' are the expected functions
+            // ie: ones="abc"; ones(1) !!!
+            if (name == L"ones" || name == L"zeros")
             {
+                const ast::exps_t args = ce.getArgs();
+                switch (args.size())
+                {
                 case 0:
                     return true;
                 case 1:
@@ -206,30 +206,231 @@ bool AnalysisVisitor::isDoubleConstant(const ast::Exp & e)
                     return isDoubleConstant(*args.front()) && isDoubleConstant(**std::next(args.cbegin()));
                 default:
                     return false;
+                }
             }
         }
+
+        return false;
     }
 
-    return false;
-}
+    bool AnalysisVisitor::asDoubleMatrix(ast::Exp & e, types::Double *& data)
+    {
+        if (isDoubleConstant(e))
+        {
+            ast::ExecVisitor exec;
+            e.accept(exec);
+            types::InternalType * pIT = exec.getResult();
+            // TODO : handle complex case
+            if (pIT && pIT->isDouble() && !pIT->getAs<types::Double>()->isComplex())
+            {
+                pIT->IncreaseRef();
+                data = static_cast<types::Double *>(pIT);
 
-bool AnalysisVisitor::asDoubleMatrix(ast::Exp & e, types::Double *& data)
-{
-    if (isDoubleConstant(e))
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, const ast::exps_t & args)
     {
-        ast::ExecVisitor exec;
-        e.accept(exec);
-        types::InternalType * pIT = exec.getResult();
-        // TODO : handle complex case
-        if (pIT && pIT->isDouble() && !pIT->getAs<types::Double>()->isComplex())
+        std::vector<Result> resargs;
+        std::vector<TIType> vargs;
+        vargs.reserve(args.size());
+        resargs.reserve(args.size());
+
+        for (auto arg : args)
         {
-            pIT->IncreaseRef();
-            data = static_cast<types::Double *>(pIT);
+            arg->accept(*this);
+            resargs.push_back(getResult());
+            vargs.push_back(getResult().getType());
+        }
 
-            return true;
+        const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
+       std::vector<TIType> out = getDM().call(*this, lhs, sym, vargs, &e);
+        if (lhs > 1)
+        {
+            multipleLHS.clear();
+            multipleLHS.reserve(out.size());
+            for (const auto & type : out)
+            {
+               const int tempId = getDM().getTmpId(type, false);
+                multipleLHS.emplace_back(type, tempId);
+            }
+
+           for (const auto & resarg : resargs)
+           {
+               getDM().releaseTmp(resarg.getTempId());
+           }
         }
+        else if (lhs == 1)
+       {
+           int tempId = -1;
+           if (resargs.size() == 1)
+           {
+               const int id = resargs.back().getTempId();
+               if (id != -1 && Checkers::isElementWise(name) && out[0] == resargs.back().getType())
+               {
+                   tempId = id;
+               }
+           }
+           if (tempId == -1)
+           {
+               tempId = getDM().getTmpId(out[0], false);
+               for (const auto & resarg : resargs)
+               {
+                   getDM().releaseTmp(resarg.getTempId());
+               }
+           }
+           
+           e.getDecorator().res = Result(out[0], tempId);
+           e.getDecorator().setCall(name, vargs);
+           setResult(e.getDecorator().res);
+       }
     }
 
-    return false;
-}
+    int AnalysisVisitor::getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR)
+    {
+        int tempId = -1;
+        if (resT.isknown() && resT.ismatrix())
+        {
+            if (LR.isTemp() || RR.isTemp())
+            {
+                const int Lid = LR.getTempId();
+                const int Rid = RR.getTempId();
+                const TIType & LT = LR.getType();
+                const TIType & RT = RR.getType();
+
+                if (LT.isscalar())
+                {
+                    if (RT.isscalar())
+                    {
+                        if (Lid == -1)
+                        {
+                            if (resT == LT)
+                            {
+                                tempId = Rid;
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid);
+                            }
+                        }
+                        else
+                        {
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                                getDM().releaseTmp(Rid);
+                            }
+                           else if (Rid != -1 && resT == RT)
+                           {
+                                tempId = Rid;
+                                getDM().releaseTmp(Lid);
+                           }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (Rid == -1)
+                        {
+                            tempId = getDM().getTmpId(resT, false);
+                        }
+                        else
+                        {
+                            if (resT == RT)
+                            {
+                                tempId = Rid;
+                            }
+                           else if (Lid != -1 && resT == LT)
+                           {
+                               tempId = Lid;
+                               getDM().releaseTmp(Rid);
+                           }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid);
+                            }
+                        }
+                        getDM().releaseTmp(Lid);
+                    }
+                }
+                else
+                {
+                    if (RT.isscalar())
+                    {
+                        if (Lid == -1)
+                        {
+                            tempId = getDM().getTmpId(resT, false);
+                        }
+                        else
+                        {
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                            }
+                           else if (Rid != -1 && resT == RT)
+                           {
+                               tempId = Rid;
+                               getDM().releaseTmp(Lid);
+                           }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid);
+                            }
+                        }
+                        getDM().releaseTmp(Rid);
+                    }
+                    else
+                    {
+                        if (Rid == -1)
+                        {
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid);
+                            }
+                        }
+                        else
+                        {
+                            if (resT == RT)
+                            {
+                                tempId = Rid;
+                            }
+                           else if (Lid != -1 && resT == LT)
+                           {
+                               tempId = Lid;
+                               getDM().releaseTmp(Rid);
+                           }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid);
+                            }
+                            getDM().releaseTmp(Lid);
+                        }
+                    }
+                }
+            }
+           else
+           {
+               tempId = getDM().getTmpId(resT, false);
+           }
+        }
+
+        return tempId;
+    }
 }
index c2a1275..54de1d5 100644 (file)
@@ -104,9 +104,9 @@ bool ArgnAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
         case LHS:
         case RHS:
         {
-            const unsigned int val = kind == LHS ? fblock->getLHS() : fblock->getRHS();
+            const int64_t val = kind == LHS ? fblock->getLHS() : fblock->getRHS();
             Result & res = e.getDecorator().setResult(type);
-            res.getConstant() = visitor.getGVN().getValue((double)val);
+            res.getConstant() = visitor.getGVN().getValue(val);
             e.getDecorator().setCall(L"argn");
             visitor.setResult(res);
         }
@@ -116,12 +116,12 @@ bool ArgnAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
             mlhs.clear();
             mlhs.reserve(2);
 
-            const unsigned int flhs = fblock->getLHS();
-            const unsigned int frhs = fblock->getRHS();
+            const int64_t flhs = fblock->getLHS();
+            const int64_t frhs = fblock->getRHS();
             mlhs.emplace_back(type);
-            mlhs.back().getConstant() = visitor.getGVN().getValue((double)flhs);
+            mlhs.back().getConstant() = visitor.getGVN().getValue(flhs);
             mlhs.emplace_back(type);
-            mlhs.back().getConstant() = visitor.getGVN().getValue((double)frhs);
+            mlhs.back().getConstant() = visitor.getGVN().getValue(frhs);
 
             e.getDecorator().setCall(L"argn");
         }
index 48aff2d..7d40c21 100644 (file)
@@ -184,11 +184,38 @@ namespace analysis
         return info;
     }
 
-    Info & Block::addDefine(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
+    void Block::addLocal(const symbol::Symbol & sym, const TIType & type, const bool isAnInt)
+    {
+       if (parent)
+       {
+           parent->addLocal(sym, type, isAnInt);
+       }
+    }
+
+    int Block::getTmpId(const TIType & type, const bool isAnInt)
+    {
+       if (parent)
+       {
+           return parent->getTmpId(type, isAnInt);
+       }
+
+       return -1;
+    }
+    
+    void Block::releaseTmp(const int id)
+    {
+       if (parent)
+       {
+           parent->releaseTmp(id);
+       }
+    }
+
+    Info & Block::addDefine(const symbol::Symbol & sym, const TIType & Rtype, const bool isIntIterator, ast::Exp * exp)
     {
         /* DEFINE:
            - if associated data is shared then we need to clone it
         */
+       addLocal(sym, Rtype, isIntIterator);
         Info & info = putAndClear(sym, exp);
         info.cleared = false;
         info.data = new Data(true, sym);
@@ -201,6 +228,7 @@ namespace analysis
 
     Info & Block::addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
     {
+       addLocal(Lsym, Rtype, /* isIntIterator */ false);
         Info & Linfo = putAndClear(Lsym, exp);
         Info & Rinfo = putSymsInScope(Rsym);
         Linfo.cleared = false;
@@ -221,7 +249,7 @@ namespace analysis
     Info & Block::addMacroDef(ast::FunctionDec * dec)
     {
         TIType ty(getGVN(), TIType::MACRO);
-       Info & i = addDefine(dec->getSymbol(), ty, dec);
+       Info & i = addDefine(dec->getSymbol(), ty, false, dec);
        i.exp = dec;
 
        return i;
@@ -266,8 +294,7 @@ namespace analysis
         {
             if (pIT)
             {
-                ExistingMacroDef macrodef(*static_cast<types::Macro *>(pIT));
-                visitor.getPMC().getOutTypes(visitor, &macrodef, in, out);
+                visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
             }
             else
             {
@@ -279,8 +306,7 @@ namespace analysis
                 else
                 {
                     DataManager::getSymInScilabContext(getGVN(), sym, pIT);
-                    ExistingMacroDef macrodef(*static_cast<types::Macro *>(pIT));
-                    visitor.getPMC().getOutTypes(visitor, &macrodef, in, out);
+                    visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
                 }
             }
             break;
@@ -288,8 +314,7 @@ namespace analysis
         case TIType::MACROFILE:
         {
            DataManager::getSymInScilabContext(getGVN(), sym, pIT);
-           ExistingMacroDef macrodef(*static_cast<types::MacroFile *>(pIT)->getMacro());
-           visitor.getPMC().getOutTypes(visitor, &macrodef, in, out);
+           visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::MacroFile *>(pIT)->getMacro()), in, out);
             break;
         }
         default:
index 3478aba..5dd9e68 100644 (file)
@@ -40,7 +40,7 @@ const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, cons
         FunctionBlock & fblock = *static_cast<FunctionBlock *>(dm.getCurrent());
         fblock.setName(macrodef->getName());
         fblock.setLhsRhs(signature.lhs, rhs);
-        fblock.setInOut(macrodef);
+        fblock.setInOut(macrodef, rhs, in);
        fblock.setGlobals(macrodef->getGlobals());
         if (!fblock.addIn(signature.tuple, values))
         {
@@ -48,9 +48,10 @@ const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, cons
             return nullptr;
         }
 
-        macrodef->getBody().accept(visitor);
-       //macrodef->getBody().accept(visitor.getPV());
+        fblock.getExp()->accept(visitor);
         dm.finalizeBlock();
+       visitor.emitFunctionBlock(fblock);
+       //std::wcerr << fblock << std::endl;
         outMap.emplace_back(fblock.getConstraints(), fblock.getGlobalConstants(), fblock.getOuts());
 
         return &outMap.back().out;
index a783910..66a54c2 100644 (file)
@@ -177,9 +177,9 @@ namespace analysis
                {
                    const double x = pDbl->get()[0];
                    int64_t i;
-                   if (tools::asInteger<int64_t>(x, i))
+                   if (tools::asInteger(x, i))
                    {
-                       _val = gvn.getValue((double)i);
+                       _val = gvn.getValue(i);
                        return true;
                    }
                 }
@@ -209,7 +209,7 @@ namespace analysis
             {
                 if (gvnValue->poly->isConstant())
                 {
-                    _val = gvnValue->poly->constant;
+                    _val = (double)gvnValue->poly->constant;
                     return true;
                 }
             }
@@ -237,7 +237,7 @@ namespace analysis
             {
                 if (gvnValue->poly->isConstant())
                 {
-                    _val = gvnValue->poly->constant;
+                    _val = gvnValue->poly->constant != 0;
                     return true;
                 }
             }
@@ -271,7 +271,8 @@ namespace analysis
             {
                 if (gvnValue->poly->isConstant())
                 {
-                    _val = gvnValue->poly->constant;
+                    _val.real((double)gvnValue->poly->constant);
+                   _val.imag(0.);
                     return true;
                 }
             }
index 22f8c8d..2da2b17 100644 (file)
@@ -61,7 +61,7 @@ bool DiagAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
     bool isOneDim = false;
     GVN::Value * dim;
     TIType & type = R1.getType();
-    GVN::Value * ONE = visitor.getGVN().getValue(1.);
+    GVN::Value * ONE = visitor.getGVN().getValue(1);
     isOneDim = visitor.getCM().check(ConstraintManager::EQUAL, type.rows.getValue(), ONE);
     if (isOneDim)
     {
@@ -80,7 +80,7 @@ bool DiagAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
     {
         SymbolicDimension sdim = index == 0 ? SymbolicDimension(&visitor.getGVN(), dim) : SymbolicDimension(&visitor.getGVN(), visitor.getGVN().getValue(OpValue::Kind::PLUS, *dim, *visitor.getGVN().getValue(std::abs(index))));
         TIType resT(visitor.getGVN(), R1.getType().type, sdim, sdim);
-        e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+        e.getDecorator().setResult(Result(resT, visitor.getDM().getTmpId(resT, false)));
     }
     else
     {
@@ -89,7 +89,7 @@ bool DiagAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
         {
             SymbolicDimension dimONE(visitor.getGVN(), 1.);
             TIType resT(visitor.getGVN(), R1.getType().type, type.rows, dimONE);
-            e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+            e.getDecorator().setResult(Result(resT, visitor.getDM().getTmpId(resT, false)));
         }
         else
         {
@@ -100,7 +100,7 @@ bool DiagAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
                 {
                     SymbolicDimension dimONE(visitor.getGVN(), 1);
                     TIType resT(visitor.getGVN(), R1.getType().type, type.cols, dimONE);
-                    e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+                    e.getDecorator().setResult(Result(resT, visitor.getDM().getTmpId(resT, false)));
                 }
                 else
                 {
@@ -116,7 +116,7 @@ bool DiagAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
                     {
                         SymbolicDimension dimONE(visitor.getGVN(), 1);
                         TIType resT(visitor.getGVN(), R1.getType().type, type.rows, dimONE);
-                        e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+                        e.getDecorator().setResult(Result(resT, visitor.getDM().getTmpId(resT, false)));
                     }
                     else
                     {
index 25037f3..292c20b 100644 (file)
@@ -10,6 +10,9 @@
  *
  */
 
+#include "debugvisitor.hxx"
+#include "printvisitor.hxx"
+
 #include "data/DataManager.hxx"
 #include "data/FunctionBlock.hxx"
 #include "data/CompleteMacroSignature.hxx"
@@ -56,7 +59,8 @@ namespace analysis
 
     void FunctionBlock::setGlobals(const std::set<symbol::Symbol> & v)
     {
-       globals = v;
+       //globals = v; => bug on mac
+       std::copy(v.begin(), v.end(), std::inserter(globals, globals.begin()));
     }
 
 /*    TITypeSignatureTuple FunctionBlock::getGlobals(std::vector<symbol::Symbol> & v)
@@ -123,28 +127,78 @@ namespace analysis
     void FunctionBlock::finalize()
     {
         dm->popFunction();
+
+       for (unsigned int i = 0; i != lhs; ++i)
+       {
+           auto it = symMap.find(out[i]);
+           if (it != symMap.end())
+           {
+               const TIType & type = it->second.type;
+               if (type.isscalar())
+               {
+                   types_out.emplace_back(out[i], TypeLocal(type.type, 1, 1, false));
+               }
+               else
+               {
+                   types_out.emplace_back(out[i], TypeLocal(type.type, -1, -1, false));
+               }
+           }
+           else
+           {
+               types_out.emplace_back(out[i], TypeLocal(TIType::UNKNOWN, -1, -1, false));
+           }
+           
+           auto jt = locals.find(out[i]);
+           if (jt != locals.end())
+           {
+               jt->second.erase(types_out.back().second);
+               if (jt->second.empty())
+               {
+                   locals.erase(jt);
+               }
+           }
+       }
     }
 
-    Info & FunctionBlock::addDefine(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
+    void FunctionBlock::addLocal(const symbol::Symbol & sym, const TIType & type, const bool isAnInt)
     {
-       Info & info = Block::addDefine(sym, Rtype, exp);
        auto i = locals.find(sym);
        if (i == locals.end())
        {
-           i = locals.emplace(sym, std::set<__TypeLocal>()).first;
+           i = locals.emplace(sym, std::set<TypeLocal>()).first;
        }
-       if (Rtype.isConstantDims())
-       {
-           i->second.emplace(Rtype.type, Rtype.rows.getConstant(), Rtype.cols.getConstant());
-       }
-       else
+
+       i->second.emplace(TypeLocal::get(type, isAnInt));
+    }
+
+    int FunctionBlock::getTmpId(const TIType & type, const bool isAnInt)
+    {
+       return tempManager.getTmp(type, isAnInt);
+    }
+    
+    void FunctionBlock::releaseTmp(const int id)
+    {
+       tempManager.releaseTmp(id);
+    }
+
+    void FunctionBlock::setInOut(MacroDef * macrodef, const unsigned int rhs, const std::vector<TIType> & _in)
+    {
+        in = macrodef->getIn();
+        out = macrodef->getOut();
+
+       for (unsigned int i = 0; i != rhs; ++i)
        {
-           i->second.emplace(Rtype.type, -1, -1);
+           if (_in[i].isscalar())
+           {
+               types_in.emplace_back(in[i], TypeLocal(_in[i].type, 1, 1, false));
+           }
+           else
+           {
+               types_in.emplace_back(in[i], TypeLocal(_in[i].type, -1, -1, false));
+           }
        }
-         
-        return info;
     }
-
+    
     Block * FunctionBlock::getDefBlock(const symbol::Symbol & sym, std::map<symbol::Symbol, Info>::iterator & it, const bool global)
     {
        it = symMap.find(sym);
@@ -167,4 +221,61 @@ namespace analysis
        }
        return this;
     }
+
+    std::wostream & operator<<(std::wostream & out, const FunctionBlock & fblock)
+    {
+       out << L"Function " << fblock.name << L'\n'
+           << L" -LHS: " << fblock.lhs << L'\n'
+           << L" -RHS: " << fblock.rhs << L'\n'
+           << L" -in:" << L'\n';
+       for (const auto & p : fblock.types_in)
+       {
+           out << L"   -" << p.first << L" -> " << p.second << L'\n';
+       }
+
+       out << L'\n'
+           << L" -out:" << L'\n';
+       for (const auto & p : fblock.types_out)
+       {
+           out << L"   -" << p.first << L" -> " << p.second << L'\n';
+       }
+       out << L'\n';
+       if (fblock.locals.empty())
+       {
+           out << L" -locals: none" << L'\n';
+       }
+       else
+       {
+           out << L" -locals:" << L'\n';
+           for (const auto & p : fblock.locals)
+           {
+               out << L"   -" << p.first << L" -> ";
+               tools::printSet(p.second, out);
+               out << L'\n';
+           }
+       }
+
+       out << L'\n';
+       const std::map<TypeLocal, std::stack<int>> & temps = fblock.getTemp();
+       if (temps.empty())
+       {
+           out << L" -temps: none" << L'\n';
+       }
+       else
+       {
+           out << L" -temps:" << L'\n';
+           for (const auto & p : temps)
+           {
+               out << L"   -" << p.first << L" -> " << p.second.size() << L'\n';
+           }
+       }
+
+       //ast::PrintVisitor pv(out, true, false);
+       //fblock.exp->accept(pv);
+
+       ast::DebugVisitor dv(out);
+       fblock.exp->accept(dv);
+
+       return out;
+    }
 }
index 10c4fb0..f2266f4 100644 (file)
@@ -111,58 +111,76 @@ namespace analysis
 
                    const double * real = pDbl->getReal();
                    const int size = pDbl->getSize();
-                   double max = real[0];
-                   double min = max;
-
-                    if (!pDbl->isComplex())
-                    {
-                        for (int i = 0; i < size; ++i)
-                        {
-                            if (real[i] < min)
-                            {
-                                min = real[i];
-                            }
-                            else if (real[i] > max)
-                            {
-                                max = real[i];
-                            }
-                        }
-
-                       out = SymbolicDimension(getGVN(), (double)size);
-                       safe = (min >= 1) && getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue(max));
-                        return true;
-                    }
-                   else
+                   int64_t max;
+                   if (tools::asInteger(real[0], max))
                    {
-                       const double * imag = pDbl->getImg();
-                       int i;
-                        for (i = 0; i < size; ++i)
-                        {
-                           if (imag[i])
+                       int64_t min = max;
+                       if (!pDbl->isComplex())
+                       {
+                           for (int i = 0; i < size; ++i)
                            {
-                               break;
+                               int64_t _real;
+                               if (tools::asInteger(real[i], _real))
+                               {
+                                   if (_real < min)
+                                   {
+                                       min = _real;
+                                   }
+                                   else if (_real > max)
+                                   {
+                                       max = _real;
+                                   }
+                               }
+                               else
+                               {
+                                   return false;
+                               }
                            }
-                            if (real[i] < min)
-                            {
-                                min = real[i];
-                            }
-                            else if (real[i] > max)
-                            {
-                                max = real[i];
-                            }
-                        }
-
-                       if (i == size)
-                       {
-                           out = SymbolicDimension(getGVN(), (double)size);
+                           
+                           out = SymbolicDimension(getGVN(), size);
                            safe = (min >= 1) && getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue(max));
                            return true;
                        }
                        else
                        {
-                           return false;
+                           const double * imag = pDbl->getImg();
+                           int i;
+                           for (i = 0; i < size; ++i)
+                           {
+                               if (imag[i])
+                               {
+                                   break;
+                               }
+                               int64_t _real;
+                               if (tools::asInteger(real[i], _real))
+                               {
+                                   if (_real < min)
+                                   {
+                                       min = _real;
+                                   }
+                                   else if (_real > max)
+                                   {
+                                       max = _real;
+                                   }
+                               }
+                           }
+
+                           if (i == size)
+                           {
+                               out = SymbolicDimension(getGVN(), size);
+                               safe = (min >= 1) && getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue(max));
+                               return true;
+                           }
+                           else
+                           {
+                               return false;
+                           }
                        }
                    }
+                   else
+                   {
+                       return false;
+                   }
                 }
                 else if (pIT->isImplicitList())
                 {
@@ -202,8 +220,8 @@ namespace analysis
                                 min = (uint64_t)(start + (N - 1) * step);
                             }
 
-                           out = SymbolicDimension(getGVN(), (double)N);
-                           safe = (min >= 1) && getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue((double)max));
+                           out = SymbolicDimension(getGVN(), N);
+                           safe = (min >= 1) && getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue((int64_t)max));
                            return true;
                        }
                         }
@@ -239,7 +257,7 @@ namespace analysis
                         }
                     }
 
-                   out = SymbolicDimension(getGVN(), (double)count);
+                   out = SymbolicDimension(getGVN(), count);
                    safe = getCM().check(ConstraintManager::GREATER, dim.getValue(), getGVN().getValue(max));
                    return true;
                 }
@@ -292,7 +310,9 @@ namespace analysis
 
                return true;
            }
-           
+
+           // To use with find
+           // e.g. a(find(a > 0)): find(a > 0) return a matrix where the max index is rc(a) so the extraction is safe
             if (_res.getType().ismatrix() && _res.getType().type != TIType::BOOLEAN)
             {
                out = _res.getType().rows * _res.getType().cols;
index 0efc839..b06eed4 100644 (file)
 
 namespace analysis
 {
-    ExistingMacroDef::ExistingMacroDef(types::Macro & _macro) : MacroDef(_macro.outputs_get()->size(), _macro.inputs_get()->size()), name(_macro.getName()), se(_macro.getBody()->clone()), inputs(MacroDef::asVector(_macro.inputs_get())), outputs(MacroDef::asVector(_macro.outputs_get()))
+    ExistingMacroDef::ExistingMacroDef(types::Macro & _macro) : MacroDef(_macro.outputs_get()->size(), _macro.inputs_get()->size(), _macro.getBody()), name(_macro.getName()), se(nullptr), inputs(MacroDef::asVector(_macro.inputs_get())), outputs(MacroDef::asVector(_macro.outputs_get()))
     {
         GlobalsCollector::collect(*this);
     }
 
-    ExistingMacroDef::ExistingMacroDef(const ExistingMacroDef & emd) : MacroDef(emd.inputs.size(), emd.outputs.size()), name(emd.name), se(emd.se->clone()), inputs(emd.inputs), outputs(emd.outputs)
+    ExistingMacroDef::ExistingMacroDef(const ExistingMacroDef & emd) : MacroDef(emd.inputs.size(), emd.outputs.size(), emd.original), name(emd.name), se(emd.se->clone()), inputs(emd.inputs), outputs(emd.outputs)
     {
         GlobalsCollector::collect(*this);
     }
 
     ast::SeqExp & ExistingMacroDef::getBody()
     {
+       se = static_cast<ast::SeqExp *>(original)->clone();
         return *se;
     }
 
@@ -50,34 +51,35 @@ namespace analysis
         return new ExistingMacroDef(*this);
     }
 
-    DeclaredMacroDef::DeclaredMacroDef(ast::FunctionDec * const _dec) : MacroDef(_dec->getReturns().getVars().size(), _dec->getArgs().getVars().size()), dec(_dec->clone())
+    DeclaredMacroDef::DeclaredMacroDef(ast::FunctionDec * const _dec) : MacroDef(_dec->getReturns().getVars().size(), _dec->getArgs().getVars().size(), dec), dec(nullptr)
     {
         GlobalsCollector::collect(*this);
     }
 
     ast::SeqExp & DeclaredMacroDef::getBody()
     {
+       dec = static_cast<ast::FunctionDec *>(original)->clone();
         return static_cast<ast::SeqExp &>(dec->getBody());
     }
 
     const std::wstring & DeclaredMacroDef::getName()
     {
-        return dec->getSymbol().getName();
+        return static_cast<ast::FunctionDec *>(original)->getSymbol().getName();
     }
 
     std::vector<symbol::Symbol> DeclaredMacroDef::getIn()
     {
-        return MacroDef::asVector(&dec->getArgs().getVars());
+        return MacroDef::asVector(&static_cast<ast::FunctionDec *>(original)->getArgs().getVars());
     }
 
     std::vector<symbol::Symbol> DeclaredMacroDef::getOut()
     {
-        return MacroDef::asVector(&dec->getReturns().getVars());
+        return MacroDef::asVector(&static_cast<ast::FunctionDec *>(original)->getReturns().getVars());
     }
 
     MacroDef * DeclaredMacroDef::clone() const
     {
-        return new DeclaredMacroDef(dec);
+        return new DeclaredMacroDef(dec ? dec : static_cast<ast::FunctionDec *>(original));
     }
 
 } // namespace analysis
index 81277bb..5d81687 100644 (file)
@@ -125,7 +125,16 @@ namespace analysis
         }
 
         TIType resT(visitor.getGVN(), R1.getType().type, rows, cols);
-        Result & _res = e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+       int tempId;
+       if (R1.getTempId() != -1)
+       {
+           tempId = R1.getTempId();
+       }
+       else
+       {
+           tempId = visitor.getDM().getTmpId(resT, false);
+       }
+        Result & _res = e.getDecorator().setResult(Result(resT, tempId));
         visitor.setResult(_res);
         return true;
     }
@@ -182,7 +191,16 @@ namespace analysis
            if (res)
            {
                TIType resT(visitor.getGVN(), R1.getType().type, rows, cols);
-               Result & _res = e.getDecorator().setResult(Result(resT, visitor.getTemp().add(resT)));
+               int tempId;
+               if (R1.getTempId() != -1)
+               {
+                   tempId = R1.getTempId();
+               }
+               else
+               {
+                   tempId = visitor.getDM().getTmpId(resT, false);
+               }
+               Result & _res = e.getDecorator().setResult(Result(resT, tempId));
                visitor.setResult(_res);
 
                return true;
index 1679ad3..623340a 100644 (file)
@@ -17,12 +17,14 @@ namespace analysis
 {
     bool AnalysisVisitor::operGVNValues(ast::OpExp & oe)
     {
-        const Result & resL = oe.getLeft().getDecorator().getResult();
-        const Result & resR = oe.getRight().getDecorator().getResult();
+        Result & resL = oe.getLeft().getDecorator().getResult();
+        Result & resR = oe.getRight().getDecorator().getResult();
         const ConstantValue & valL = resL.getConstant();
         const ConstantValue & valR = resR.getConstant();
         GVN::Value * gvnL = nullptr;
         GVN::Value * gvnR = nullptr;
+       bool LisInt = false;
+       bool RisInt = false;
 
         if (valL.getKind() == ConstantValue::GVNVAL)
         {
@@ -34,6 +36,7 @@ namespace analysis
             if (valL.getDblValue(val) && tools::isAnInt(val))
             {
                 gvnL = getGVN().getValue(val);
+               LisInt = true;
             }
         }
 
@@ -47,75 +50,146 @@ namespace analysis
             if (valR.getDblValue(val) && tools::isAnInt(val))
             {
                 gvnR = getGVN().getValue(val);
+               RisInt = true;
             }
         }
 
         if (gvnL && gvnR)
         {
-           TIType typ(getGVN(), TIType::DOUBLE, 1, 1);
-        
+            TIType typ(getGVN(), TIType::DOUBLE, 1, 1);
+
             switch (oe.getOper())
             {
             case ast::OpExp::plus:
             {
+               if (LisInt)
+               {
+                   resL.getConstant() = gvnL;
+               }
+               if (RisInt)
+               {
+                   resR.getConstant() = gvnR;
+               }
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::PLUS, *gvnL, *gvnR);
-               setResult(res);
-               return true;
+               oe.getDecorator().safe = true;
+                setResult(res);
+                return true;
             }
             case ast::OpExp::minus:
             {
+               if (LisInt)
+               {
+                   resL.getConstant() = gvnL;
+               }
+               if (RisInt)
+               {
+                   resR.getConstant() = gvnR;
+               }
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::MINUS, *gvnL, *gvnR);
+               oe.getDecorator().safe = true;
                setResult(res);
-               return true;
+                return true;
                 break;
             }
             case ast::OpExp::times:
             {
+                if (LisInt)
+               {
+                   resL.getConstant() = gvnL;
+               }
+               if (RisInt)
+               {
+                   resR.getConstant() = gvnR;
+               }
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::TIMES, *gvnL, *gvnR);
+                oe.getDecorator().safe = true;
                setResult(res);
-               return true;
+                return true;
             }
             case ast::OpExp::dottimes:
             {
+                if (LisInt)
+               {
+                   resL.getConstant() = gvnL;
+               }
+               if (RisInt)
+               {
+                   resR.getConstant() = gvnR;
+               }
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::DOTTIMES, *gvnL, *gvnR);
+                oe.getDecorator().safe = true;
                setResult(res);
-               return true;
+                return true;
             }
             case ast::OpExp::power:
             {
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::POWER, *gvnL, *gvnR);
+                oe.getDecorator().safe = true;
                setResult(res);
-               return true;
+                return true;
             }
             case ast::OpExp::dotpower:
             {
+                if (LisInt)
+               {
+                   resL.getConstant() = gvnL;
+               }
+               if (RisInt)
+               {
+                   resR.getConstant() = gvnR;
+               }
                 Result & res = oe.getDecorator().setResult(typ);
                 res.getConstant() = getGVN().getValue(OpValue::DOTPOWER, *gvnL, *gvnR);
+                oe.getDecorator().safe = true;
                setResult(res);
-               return true;
+                return true;
             }
             case ast::OpExp::rdivide:
             {
-                Result & res = oe.getDecorator().setResult(typ);
-                res.getConstant() = getGVN().getValue(OpValue::RDIV, *gvnL, *gvnR);
-               setResult(res);
-               return true;
+                if (gvnL->poly->isDivisibleBy(*gvnR->poly))
+                {
+                    if (LisInt)
+                   {
+                       resL.getConstant() = gvnL;
+                   }
+                   if (RisInt)
+                   {
+                       resR.getConstant() = gvnR;
+                   }
+                   Result & res = oe.getDecorator().setResult(typ);
+                    res.getConstant() = getGVN().getValue(OpValue::RDIV, *gvnL, *gvnR);
+                    oe.getDecorator().safe = true;
+                   setResult(res);
+                    return true;
+                }
             }
             case ast::OpExp::dotrdivide:
             {
-                Result & res = oe.getDecorator().setResult(typ);
-                res.getConstant() = getGVN().getValue(OpValue::DOTRDIV, *gvnL, *gvnR);
-               setResult(res);
-               return true;
+                if (gvnL->poly->isDivisibleBy(*gvnR->poly))
+                {
+                    if (LisInt)
+                   {
+                       resL.getConstant() = gvnL;
+                   }
+                   if (RisInt)
+                   {
+                       resR.getConstant() = gvnR;
+                   }
+                   Result & res = oe.getDecorator().setResult(typ);
+                    res.getConstant() = getGVN().getValue(OpValue::DOTRDIV, *gvnL, *gvnR);
+                    oe.getDecorator().safe = true;
+                   setResult(res);
+                    return true;
+                }
             }
             }
         }
 
-       return false;
+        return false;
     }
 }
index c00ccdf..31dc8d3 100644 (file)
@@ -20,14 +20,18 @@ namespace analysis
         const ast::OpExp::Oper oper = oe.getOper();
         if (oper == ast::OpExp::plus || oper == ast::OpExp::minus || oper == ast::OpExp::times || oper == ast::OpExp::rdivide)
         {
-            const Result & resL = oe.getLeft().getDecorator().getResult();
-            const Result & resR = oe.getRight().getDecorator().getResult();
+            Result & resL = oe.getLeft().getDecorator().getResult();
+            Result & resR = oe.getRight().getDecorator().getResult();
             const SymbolicRange & rangeL = resL.getRange();
             const SymbolicRange & rangeR = resR.getRange();
             const bool validL = rangeL.isValid();
             const bool validR = rangeR.isValid();
             SymbolicRange rangeOpL, rangeOpR;
             bool have2Ranges = false;
+           bool LisInt = false;
+           bool RisInt = false;
+           GVN::Value * gvnR;
+           GVN::Value * gvnL;
 
             if (validL && validR)
             {
@@ -38,9 +42,9 @@ namespace analysis
             else if (validL)
             {
                 rangeOpL = rangeL;
-                GVN::Value * gvnR;
                 if (resR.getConstant().getGVNValue(getGVN(), gvnR))
                 {
+                   RisInt = true;
                     rangeOpR.set(getGVN(), gvnR, gvnR);
                     have2Ranges = true;
                 }
@@ -48,9 +52,9 @@ namespace analysis
             else if (validR)
             {
                 rangeOpR = rangeR;
-                GVN::Value * gvnL;
                 if (resL.getConstant().getGVNValue(getGVN(), gvnL))
                 {
+                   LisInt = true;
                     rangeOpL.set(getGVN(), gvnL, gvnL);
                     have2Ranges = true;
                 }
@@ -63,31 +67,70 @@ namespace analysis
                {
                case ast::OpExp::plus:
                {
+                   if (LisInt)
+                   {
+                       resL.getConstant() = gvnL;
+                   }
+                   if (RisInt)
+                   {
+                       resR.getConstant() = gvnR;
+                   }
                    Result & res = oe.getDecorator().setResult(typ);
                    res.getRange() = rangeOpL + rangeOpR;
+                   oe.getDecorator().safe = true;
                    setResult(res);
                    return true;
                }
                case ast::OpExp::minus:
                {
+                   if (LisInt)
+                   {
+                       resL.getConstant() = gvnL;
+                   }
+                   if (RisInt)
+                   {
+                       resR.getConstant() = gvnR;
+                   }
                    Result & res = oe.getDecorator().setResult(typ);
                    res.getRange() = rangeOpL - rangeOpR;
+                   oe.getDecorator().safe = true;
                    setResult(res);
                    return true;
                }
                case ast::OpExp::times:
                {
+                   if (LisInt)
+                   {
+                       resL.getConstant() = gvnL;
+                   }
+                   if (RisInt)
+                   {
+                       resR.getConstant() = gvnR;
+                   }
                    Result & res = oe.getDecorator().setResult(typ);
                    res.getRange() = rangeOpL * rangeOpR;
+                   oe.getDecorator().safe = true;
                    setResult(res);
                    return true;
                }
                case ast::OpExp::rdivide:
                {
-                   Result & res = oe.getDecorator().setResult(typ);
-                   res.getRange() = rangeOpL / rangeOpR;
-                   setResult(res);
-                   return true;
+                   if (rangeOpL.getStart()->poly->isDivisibleBy(*rangeOpR.getEnd()->poly) && rangeOpL.getEnd()->poly->isDivisibleBy(*rangeOpR.getStart()->poly))
+                   {
+                       if (LisInt)
+                       {
+                           resL.getConstant() = gvnL;
+                       }
+                       if (RisInt)
+                       {
+                           resR.getConstant() = gvnR;
+                       }
+                       Result & res = oe.getDecorator().setResult(typ);
+                       res.getRange() = rangeOpL / rangeOpR;
+                       oe.getDecorator().safe = true;
+                       setResult(res);
+                       return true;
+                   }
                }
                }
             }
index efecd84..6f923f0 100644 (file)
@@ -103,7 +103,7 @@ namespace analysis
 
         const std::vector<symbol::Symbol> & declaredIn = macrodef.getIn();
         const unsigned int size = declaredIn.size();
-        DataManager & dm  = visitor.getDM();
+        DataManager & dm = visitor.getDM();
 
         if (in.size() < size)
         {
index f3c505f..c672400 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "AnalysisVisitor.hxx"
 #include "analyzers/SizeAnalyzer.hxx"
+#include "call/SizeCall.hxx"
 #include "tools.hxx"
 #include "double.hxx"
 
@@ -125,7 +126,7 @@ namespace analysis
             SymbolicDimension & rows = res.getType().rows;
             Result & _res = e.getDecorator().setResult(type);
             _res.getConstant() = rows.getValue();
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::R));
             visitor.setResult(_res);
             break;
         }
@@ -134,7 +135,7 @@ namespace analysis
             SymbolicDimension & cols = res.getType().cols;
             Result & _res = e.getDecorator().setResult(type);
             _res.getConstant() = cols.getValue();
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::C));
             visitor.setResult(_res);
             break;
         }
@@ -145,7 +146,7 @@ namespace analysis
             SymbolicDimension prod = rows * cols;
             Result & _res = e.getDecorator().setResult(type);
             _res.getConstant() = prod.getValue();
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::RC));
             visitor.setResult(_res);
             break;
         }
@@ -161,14 +162,14 @@ namespace analysis
             mlhs.emplace_back(type);
             mlhs.back().getConstant() = cols.getValue();
 
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::R_C));
             break;
         }
         case ONE:
         {
             Result & _res = e.getDecorator().setResult(type);
             _res.getConstant() = new types::Double(1);
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::ONE));
             visitor.setResult(_res);
             break;
         }
@@ -176,7 +177,7 @@ namespace analysis
         {
            TIType _type(visitor.getGVN(), TIType::DOUBLE, 1, 2);
             Result & _res = e.getDecorator().setResult(_type);
-            e.getDecorator().setCall(L"size");
+            e.getDecorator().setCall(new SizeCall(SizeCall::BOTH));
             visitor.setResult(_res);
             break;
         }
index ee5c6bb..3b52e06 100644 (file)
@@ -139,9 +139,10 @@ namespace analysis
        GVN::Value * gvnStart, * gvnStep, * gvnEnd;
        if (Rstart.getConstant().getDblValue(start))
        {
-           if (tools::isAnInt(start))
+           int64_t _start;
+           if (tools::asInteger(start, _start))
            {
-               gvnStart = visitor.getGVN().getValue(start);
+               gvnStart = visitor.getGVN().getValue(_start);
            }
            else
            {
@@ -159,9 +160,10 @@ namespace analysis
 
        if (Rstep.getConstant().getDblValue(step))
        {
-           if (tools::isAnInt(step))
+           int64_t _step;
+           if (tools::asInteger(step, _step))
            {
-               gvnStep = visitor.getGVN().getValue(step);
+               gvnStep = visitor.getGVN().getValue(_step);
            }
            else
            {
@@ -179,9 +181,10 @@ namespace analysis
 
        if (Rend.getConstant().getDblValue(end))
        {
-           if (tools::isAnInt(end))
+           int64_t _end;
+           if (tools::asInteger(end, _end))
            {
-               gvnEnd = visitor.getGVN().getValue(end);
+               gvnEnd = visitor.getGVN().getValue(_end);
            }
            else
            {
index a5afc3e..ded4dea 100644 (file)
@@ -27,7 +27,7 @@ namespace analysis
             {
                 // We have A = B (so the data associated to b is shared with a)
                 const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
-                dm.share(sym, symR, getSymInfo(symR).getType(), &e);
+                getDM().share(sym, symR, getSymInfo(symR).getType(), &e);
             }
             else
             {
@@ -52,10 +52,12 @@ namespace analysis
                 }
 
                 Result & RR = getResult();
-                // Don't remove tmp... temp.remove(RR);
+                // Don't remove tmp... temp.remove(RR); WHY THIS COMMENT ?????
+
                 var.getDecorator().res = RR;
-                Info & info = dm.define(sym, RR.getType(), &e);
+                Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
                 info.getConstant() = RR.getConstant();
+               getDM().releaseTmp(RR.getTempId());
             }
         }
         else if (e.getLeftExp().isCallExp()) // A(12) = ...
@@ -67,11 +69,12 @@ namespace analysis
                 e.getRightExp().accept(*this);
                 Result RR = getResult();
                 ce.getDecorator().res = RR;
-                Info & info = dm.write(symL, RR.getType(), &e);
+                Info & info = getDM().write(symL, RR.getType(), &e);
                 if (analyzeIndices(info.type, ce))
                {
                    e.getDecorator().safeInsertion = (RR.getType() == getResult().getType());
                }
+               getDM().releaseTmp(RR.getTempId());
             }
         }
         else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
@@ -87,10 +90,11 @@ namespace analysis
                     // TODO: handle fields...
                     if (exp->isSimpleVar() && j != multipleLHS.end())
                     {
-                        const ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
+                        ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
                         const symbol::Symbol & sym = var.getSymbol();
-                        Info & info = dm.define(sym, j->getType(), exp);
+                        Info & info = getDM().define(sym, j->getType(), j->isAnInt(), exp);
                         info.setConstant(j->getConstant());
+                       var.getDecorator().res = *j;
                         ++j;
                     }
                 }
index 7c88641..1b68f7c 100644 (file)
@@ -132,7 +132,7 @@ namespace analysis
                val->accept(*this);
                Result & res = getResult();
                TIType & ty = res.getType();
-               if (ty.ismatrix() && ty.isscalar() || (getCM().check(ConstraintManager::STRICT_POSITIVE, ty.rows.getValue()) || getCM().check(ConstraintManager::STRICT_POSITIVE, ty.cols.getValue())))
+               if ((ty.ismatrix() && ty.isscalar()) || (getCM().check(ConstraintManager::STRICT_POSITIVE, ty.rows.getValue()) || getCM().check(ConstraintManager::STRICT_POSITIVE, ty.cols.getValue())))
                {
                    if (isEq)
                    {
@@ -147,7 +147,7 @@ namespace analysis
                }
            }
        }
-       
+
         if (shortcutExp)
         {
             e.replace(shortcutExp);
index 6476bd8..8dd4f6d 100644 (file)
@@ -20,11 +20,11 @@ namespace analysis
     {
         logger.log(L"ListExp", e.getLocation());
         e.getStart().accept(*this);
-        Result Rstart = getResult();
+        Result & Rstart = e.getStart().getDecorator().getResult();
         e.getEnd().accept(*this);
-        Result Rend = getResult();
+        Result & Rend = e.getEnd().getDecorator().getResult();
         e.getStep().accept(*this);
-        Result & Rstep = getResult();
+        Result & Rstep = e.getStep().getDecorator().getResult();
 
        if (e.getParent()->isVarDec())
        {
@@ -32,7 +32,8 @@ namespace analysis
            GVN::Value * endRange;
            if (Rstart.getConstant().getGVNValue(getGVN(), startRange) && Rend.getConstant().getGVNValue(getGVN(), endRange))
            {
-               const symbol::Symbol & sym = static_cast<ast::VarDec *>(e.getParent())->getSymbol();
+               ast::VarDec & vd = *static_cast<ast::VarDec *>(e.getParent());
+               const symbol::Symbol & sym = vd.getSymbol();
                TIType typ(dm.getGVN(), TIType::DOUBLE);
                Result & res = e.getDecorator().setResult(Result(typ, -1));
                res.setRange(SymbolicRange(getGVN(), startRange, endRange));
@@ -63,7 +64,7 @@ namespace analysis
                 {
                     out = start;
                 }
-                e.getDecorator().setResult(Result(T, temp.add(T)));
+                e.getDecorator().setResult(Result(T, dm.getTmpId(T, false)));
                 break;
             }
             default:
@@ -136,7 +137,7 @@ namespace analysis
             }
         }
 
-        GVN::Value * ONEValue = getGVN().getValue(1.);
+        GVN::Value * ONEValue = getGVN().getValue(1);
         SymbolicDimension ONE(getGVN(), ONEValue);
         GVN::Value * v;
 
index 21d29a0..aefc9c9 100644 (file)
 namespace analysis
 {
 
+    
+
     void AnalysisVisitor::visit(ast::OpExp & e)
     {
         logger.log(L"OpExp", e.getLocation());
         TIType resT(getGVN());
         int tempId = -1;
+       bool safe;
 
         e.getLeft().accept(*this);
         Result LR = getResult();
@@ -38,43 +41,12 @@ namespace analysis
                 {
                 case ast::OpExp::plus :
                 {
-                    resT = check_____add____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-
-                        if (ret)
-                        {
-                            resT = check_____add____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
-                    if (resT.isscalar())
-                    {
-                    }
+                   resT = checkEWBinOp<check_____add____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::minus:
                 {
-                    resT = check_____sub____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____sub____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
-                    if (resT.isscalar())
-                    {
-                    }
+                   resT = checkEWBinOp<check_____sub____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::times:
@@ -86,12 +58,22 @@ namespace analysis
                         if (ret)
                         {
                             resT = check_____times____(getGVN(), LT, RT);
+                           safe = true;
                         }
                         else
                         {
                             resT = resT.asUnknownMatrix();
                         }
                     }
+                   else
+                   {
+                       safe = true;
+                   }
+
+                   tempId = dm.getTmpId(resT, false);
+                   dm.releaseTmp(LR.getTempId());
+                   dm.releaseTmp(RR.getTempId());
+                   
                     break;
                 }
                 case ast::OpExp::rdivide:
@@ -103,12 +85,21 @@ namespace analysis
                         if (ret)
                         {
                             resT = check_____rdivide____(getGVN(), LT, RT);
+                           safe = true;
                         }
                         else
                         {
                             resT = resT.asUnknownMatrix();
                         }
                     }
+                   else
+                   {
+                       safe = true;
+                   }
+                   
+                   tempId = dm.getTmpId(resT, false);
+                   dm.releaseTmp(LR.getTempId());
+                   dm.releaseTmp(RR.getTempId());
                     break;
                 }
                 case ast::OpExp::ldivide:
@@ -120,12 +111,21 @@ namespace analysis
                         if (ret)
                         {
                             resT = check_____ldivide____(getGVN(), LT, RT);
+                           safe = true;
                         }
                         else
                         {
                             resT = resT.asUnknownMatrix();
                         }
                     }
+                   else
+                   {
+                       safe = true;
+                   }
+                   
+                   tempId = dm.getTmpId(resT, false);
+                   dm.releaseTmp(LR.getTempId());
+                   dm.releaseTmp(RR.getTempId());
                     break;
                 }
                 case ast::OpExp::power:
@@ -137,174 +137,108 @@ namespace analysis
                         if (ret)
                         {
                             resT = check_____power____(getGVN(), LT, RT);
+                           safe = true;
                         }
                         else
                         {
                             resT = resT.asUnknownMatrix();
                         }
                     }
+                   else
+                   {
+                       safe = true;
+                   }
+                   
+                   tempId = dm.getTmpId(resT, false);
+                   dm.releaseTmp(LR.getTempId());
+                   dm.releaseTmp(RR.getTempId());
                     break;
                 }
                 case ast::OpExp::dottimes :
                 {
-                    resT = check_____dottimes____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____dottimes____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
-                    if (resT.isscalar())
-                    {
-                    }
+                   resT = checkEWBinOp<check_____dottimes____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::dotrdivide:
                 {
-                    resT = check_____dotrdiv____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::EQUAL, LT.cols.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____dotrdiv____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
-                    break;
+                   resT = checkEWBinOp<check_____dotrdiv____>(LT, RT, LR, RR, safe, tempId);
+                   break;
                 }
                 case ast::OpExp::dotpower:
                 {
-                    resT = check_____dotpower____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::EQUAL, LT.cols.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____dotpower____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
+                   resT = checkEWBinOp<check_____dotpower____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::unaryMinus :
                 {
                     resT = check_____unaryminus____(getGVN(), RT);
+                   if (!resT.hasInvalidDims())
+                   {
+                       safe = true;
+                   }
+                   tempId = RR.getTempId();
                     break;
                 }
                 case ast::OpExp::krontimes :
                 {
                     resT = check_____krontimes____(getGVN(), LT, RT);
+                   if (!resT.hasInvalidDims())
+                   {
+                       safe = true;
+                   }
+                   tempId = dm.getTmpId(resT, false);
+                   dm.releaseTmp(LR.getTempId());
+                   dm.releaseTmp(RR.getTempId());
                     break;
                 }
                 case ast::OpExp::eq:
                 {
-                    resT = check_____eq____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____eq____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::ne:
                 {
-                    resT = check_____neq____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____neq____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::lt:
                 {
-                    resT = check_____lt____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____lt____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::le:
                 {
-                    resT = check_____le____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____le____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::gt:
                 {
-                    resT = check_____gt____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____gt____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::ge:
                 {
-                    resT = check_____ge____(getGVN(), LT, RT);
+                   resT = checkEWBinOp<check_____ge____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::logicalAnd:
                 {
-                    resT = check_____and____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____and____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
+                   resT = checkEWBinOp<check_____and____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::logicalOr:
                 {
-                    resT = check_____or____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____or____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
+                   resT = checkEWBinOp<check_____or____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::logicalShortCutAnd:
                 {
-                    resT = check_____andand____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____andand____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
+                   resT = checkEWBinOp<check_____andand____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 case ast::OpExp::logicalShortCutOr:
                 {
-                    resT = check_____oror____(getGVN(), LT, RT);
-                    if (resT.hasInvalidDims())
-                    {
-                        const bool ret = getCM().check(ConstraintManager::SAMEDIMS, LT.rows.getValue(), LT.cols.getValue(), RT.rows.getValue(), RT.cols.getValue());
-                        if (ret)
-                        {
-                            resT = check_____oror____(getGVN(), LT, RT);
-                        }
-                        else
-                        {
-                            resT = resT.asUnknownMatrix();
-                        }
-                    }
+                   resT = checkEWBinOp<check_____oror____>(LT, RT, LR, RR, safe, tempId);
                     break;
                 }
                 }
@@ -316,6 +250,7 @@ namespace analysis
             }
         }
 
+       e.getDecorator().safe = safe;
         e.getDecorator().res = Result(resT, tempId);
         setResult(e.getDecorator().res);
 
@@ -329,14 +264,16 @@ namespace analysis
         e.getExp().accept(*this);
         Result & LR = getResult();
         TIType & LT = LR.getType();
+       const int tempId = LR.getTempId();
         if (LT.isknown())
         {
             TIType resT = check_____not____(getGVN(), LT);
-            e.getDecorator().res = Result(resT, -1);
+            e.getDecorator().res = Result(resT, tempId);
+           e.getDecorator().safe = true;
         }
         else
         {
-            e.getDecorator().res = Result(TIType(getGVN()), -1);
+            e.getDecorator().res = Result(TIType(getGVN()), tempId);
         }
         setResult(e.getDecorator().res);
     }
@@ -347,7 +284,11 @@ namespace analysis
         e.getExp().accept(*this);
         Result & res = getResult();
         const TIType & type = res.getType();
-        e.getDecorator().res = Result(TIType(dm.getGVN(), type.type, type.cols, type.rows));
+       TIType resType(dm.getGVN(), type.type, type.cols, type.rows);
+       e.getDecorator().res = Result(resType, dm.getTmpId(resType, false));
+       e.getDecorator().safe = true;
+       dm.releaseTmp(res.getTempId());
+       
         setResult(e.getDecorator().res);
     }
 }
index 9ac49b0..ec0061d 100644 (file)
@@ -17,45 +17,46 @@ namespace ast
 {
 static int level = -1;
 
-static void DEBUG_START_NODE(const ast::Ast& e)
+void DebugVisitor::DEBUG_START_NODE(const ast::Ast& e)
 {
-    wcerr << L"(" << e.getNodeNumber() << L") ";
+    *ostr << L"(" << e.getNodeNumber() << L") ";
     ++level;
 }
 
-static void DEBUG_END_NODE(void)
+void DebugVisitor::DEBUG_END_NODE(void)
 {
     --level;
 }
 
-static void DEBUG(wstring str)
+void DebugVisitor::DEBUG(wstring str)
 {
     for (int i = 0 ; i < level; ++i)
     {
-        wcerr << L"  ";
+        *ostr << L"  ";
     }
     if (level > 0)
     {
-        wcerr << L"     ";
+        *ostr << L"     ";
     }
-    wcerr << str << endl;
+    *ostr << str << endl;
 }
 
-static void DEBUG(wstring str, const Exp &e)
+void DebugVisitor::DEBUG(wstring str, const Exp &e)
 {
     for (int i = 0 ; i < level; ++i)
     {
-        wcerr << L"  ";
+        *ostr << L"  ";
     }
     if (level > 0)
     {
-        wcerr << L"|_./ ";
+        *ostr << L"|_./ ";
     }
-    wcerr << str;
+    *ostr << str;
 
     Location loc = e.getLocation();
-    wcerr << L" @(" << loc.first_line << L"." << loc.first_column << L" -> ";
-    wcerr << loc.last_line << L"." << loc.last_column << L")" << endl;
+    *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;
 }
 
 
index d6c9e6f..101f431 100644 (file)
@@ -13,8 +13,6 @@ out = testGVN("a=n+1;b=1+n");
 assert_checkequal(out.a, out.b);
 out = testGVN("a=n*3;b=3*n");
 assert_checkequal(out.a, out.b);
-out = testGVN("a=0.5*x;b=x/2");
-assert_checkequal(out.a, out.b);
 out = testGVN("a=2*n+1;b=1+n;c=b+n");
 assert_checkequal(out.a, out.c);
 out = testGVN("a=x+2;b=x+x*x+5+2*x-1+x;c=a*a;d=a^2;e=(x+2)*(2+x)");
index e42f9ee..cc79726 100644 (file)
@@ -19,9 +19,6 @@ assert_checkequal(out.a, out.b);
 out = testGVN("a=n*3;b=3*n");
 assert_checkequal(out.a, out.b);
 
-out = testGVN("a=0.5*x;b=x/2");
-assert_checkequal(out.a, out.b);
-
 out = testGVN("a=2*n+1;b=1+n;c=b+n");
 assert_checkequal(out.a, out.c);
 
index b0a3393..77f219b 100644 (file)
@@ -79,7 +79,7 @@ Function::ReturnValue sci_testGVN(types::typed_list &in, int _iRetCount, types::
     //gvn.print_info();
 
     Struct * pOut = new Struct(1, 1);
-    std::map<std::wstring, unsigned long long> maps = gvn.getSymMap();
+    std::map<std::wstring, uint64_t> maps = gvn.getSymMap();
     for (const auto & p : maps)
     {
         pOut->addField(p.first);