Analysis: AnalysisVisitor can now be used as a singleton and fix bugs in cache system 71/17271/2
Calixte DENIZET [Tue, 29 Sep 2015 15:43:41 +0000 (17:43 +0200)]
Change-Id: I42d5a29f6253f8562e3467dbd7c8f5f948bb767d

27 files changed:
scilab/modules/ast/includes/analysis/AnalysisVisitor.hxx
scilab/modules/ast/includes/analysis/Result.hxx
scilab/modules/ast/includes/analysis/data/Block.hxx
scilab/modules/ast/includes/analysis/data/CompleteMacroSignature.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/MacroInfo.hxx [deleted file]
scilab/modules/ast/includes/analysis/data/PolymorphicMacroCache.hxx
scilab/modules/ast/includes/analysis/data/TITypeTuple.hxx
scilab/modules/ast/includes/analysis/gvn/ConstraintManager.hxx
scilab/modules/ast/includes/analysis/gvn/InferenceConstraint.hxx
scilab/modules/ast/includes/analysis/tools.hxx
scilab/modules/ast/src/cpp/analysis/AnalysisVisitor.cpp
scilab/modules/ast/src/cpp/analysis/Block.cpp
scilab/modules/ast/src/cpp/analysis/CeilAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/CompleteMacroSignature.cpp
scilab/modules/ast/src/cpp/analysis/ConstraintManager.cpp
scilab/modules/ast/src/cpp/analysis/DataManager.cpp
scilab/modules/ast/src/cpp/analysis/FunctionBlock.cpp
scilab/modules/ast/src/cpp/analysis/GVN.cpp
scilab/modules/ast/src/cpp/analysis/InferenceConstraints.cpp
scilab/modules/ast/src/cpp/analysis/MacroDef.cpp
scilab/modules/ast/src/cpp/analysis/MultivariateMonomial.cpp
scilab/modules/ast/src/cpp/analysis/PolymorphicMacroCache.cpp
scilab/modules/ast/src/cpp/analysis/VisitCallExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitOpExp.cpp

index 2e78ec3..20b3ec8 100644 (file)
@@ -50,12 +50,10 @@ class EXTERN_AST AnalysisVisitor : public ast::Visitor, public Chrono
 public:
 
     typedef std::unordered_map<std::wstring, std::shared_ptr<CallAnalyzer>> MapSymCall;
-    typedef std::vector<Call *> Calls;
 
 private:
 
     Result _result;
-    Calls allCalls;
     DataManager dm;
     PolymorphicMacroCache pmc;
     ConstraintManager cm;
@@ -78,15 +76,8 @@ public:
     static bool asDoubleMatrix(ast::Exp & e, types::Double *& data);
     static void analyze(ast::SelectExp & e);
 
-    AnalysisVisitor() : cv(*this), pv(std::wcerr, true, false), logger("/tmp/analysis.log")
-    {
-        start_chrono();
-    }
-
-    virtual ~AnalysisVisitor()
-    {
-        //std::cerr << "delete AnalysisVisitor" << std::endl;
-    }
+    AnalysisVisitor();
+    virtual ~AnalysisVisitor();
 
     virtual AnalysisVisitor* clone()
     {
@@ -161,11 +152,6 @@ public:
         return _result;
     }
 
-    inline const Calls & getCalls() const
-    {
-        return allCalls;
-    }
-
     inline std::vector<Result> & getLHSContainer()
     {
         return multipleLHS;
@@ -214,24 +200,17 @@ public:
         return dm.getInfo(sym);
     }
 
+    void reset();
     bool analyzeIndices(TIType & type, ast::CallExp & ce);
 
     // Only for debug use
     void print_info();
     logging::Logger & getLogger();
-
+    
 private:
 
     bool getDimension(SymbolicDimension & dim, ast::Exp & arg, bool & safe, SymbolicDimension & out);
 
-    inline void pushCall(Call * c)
-    {
-        if (c)
-        {
-            allCalls.push_back(c);
-        }
-    }
-
     /*
        Workaround for a C++11 bug with Intel compiler
        https://software.intel.com/fr-fr/forums/topic/514793
index f283d84..fbe8cf0 100644 (file)
@@ -35,6 +35,7 @@ private:
 
     TIType type;
     int tempId;
+    uint64_t functionId;
     FnName fnname;
     ConstantValue constant;
     SymbolicRange range;
@@ -42,9 +43,9 @@ private:
 
 public:
 
-    Result() : type(), tempId(-1) { }
-    Result(const TIType & _type, const int _tempId = -1) : type(_type), tempId(_tempId) { }
-    Result(TIType && _type, const int _tempId = -1) : type(_type), tempId(_tempId) { }
+    Result() : type(), tempId(-1), functionId(0) { }
+    Result(const TIType & _type, const int _tempId = -1, const uint64_t _functionId = 0) : type(_type), tempId(_tempId), functionId(_functionId) { }
+    Result(TIType && _type, const int _tempId = -1, const uint64_t _functionId = 0) : type(_type), tempId(_tempId), functionId(_functionId) { }
 
     inline bool istemp() const
     {
@@ -81,6 +82,16 @@ public:
         return tempId != -1;
     }
 
+    inline void setFunctionId(const uint64_t id)
+    {
+        functionId = id;
+    }
+    
+    inline uint64_t getFunctionId() const
+    {
+        return functionId;
+    }
+
     inline bool hasGVNValue() const
     {
         return constant.getGVNValue() != nullptr;
@@ -158,6 +169,10 @@ public:
         {
             out << L", temp id:" << res.tempId;
         }
+       if (res.functionId)
+        {
+            out << L", function id:" << res.functionId;
+        }
         if (res.constant.isKnown())
         {
             out << L", constant:" << res.constant;
index 53f4243..7e88fac 100644 (file)
@@ -119,7 +119,7 @@ public:
     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);
+    virtual std::vector<TIType> addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId);
     virtual Info & addClear(const symbol::Symbol & sym, ast::Exp * exp);
 
     virtual Block * getDefBlock(const symbol::Symbol & sym, tools::SymbolMap<Info>::iterator & it, const bool global);
index f133c4c..f6dc033 100644 (file)
@@ -13,8 +13,9 @@
 #ifndef __COMPLETE_MACRO_SIGNATURE_HXX__
 #define __COMPLETE_MACRO_SIGNATURE_HXX__
 
+#include <iostream>
 #include <set>
-#include <vector>
+#include <unordered_set>
 
 #include "alltypes.hxx"
 #include "allexp.hxx"
@@ -45,23 +46,71 @@ class CompleteMacroSignature
 {
     struct __MPCMO
     {
-        MPolyConstraintSet mpConstraints;
+       uint64_t id;
+        MPolyConstraintSet verified;
+       ConstraintManager::UnverifiedSet unverified;
        std::set<symbol::Symbol> globalConstants;
         MacroOut out;
 
-        __MPCMO(const MPolyConstraintSet & _mpConstraints, const std::set<symbol::Symbol> & _globalConstants, MacroOut && _out) : mpConstraints(_mpConstraints), globalConstants(_globalConstants), out(_out) { }
+        __MPCMO(const uint64_t _id, const MPolyConstraintSet & _verified, const ConstraintManager::UnverifiedSet & _unverified, const std::set<symbol::Symbol> & _globalConstants, MacroOut && _out) : id(_id), verified(_verified), unverified(_unverified), globalConstants(_globalConstants), out(_out) { }
+
+       inline std::size_t getUnverifiedSize() const
+           {
+               std::size_t size = 0;
+               for (const auto & mpcs : unverified)
+               {
+                   size += mpcs.size();
+               }
+               return size;
+           }
+       
+       struct Compare
+       {
+           inline bool operator()(const __MPCMO & L, const __MPCMO & R) const
+               {
+                   std::size_t sizeL = L.getUnverifiedSize();
+                   std::size_t sizeR = R.getUnverifiedSize();
+                   if (sizeL < sizeR)
+                   {
+                       return true;
+                   }
+                   else if (sizeL == sizeR)
+                   {
+                       sizeL = L.verified.size();
+                       sizeR = R.verified.size();
+                       if (sizeL < sizeR)
+                       {
+                           return true;
+                       }
+                       else if (sizeL == sizeR)
+                       {
+                           return L.id < R.id;
+                       }
+                   }
+                   return false;
+               }
+       };
     };
 
+    uint64_t & id;
     // This map contains the signatures corresponding to the global symbols mapped to out types
-    std::vector<__MPCMO> outMap;
+    std::set<__MPCMO, __MPCMO::Compare> outMap;
+    GVN & gvn;
 
 public:
 
-    CompleteMacroSignature(int) { }
+    CompleteMacroSignature(GVN & _gvn, uint64_t & _id) : id(_id), gvn(_gvn) { }
 
-    const MacroOut * getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values);
+    inline GVN & getGVN()
+       {
+           return gvn;
+       }
 
-    const MacroOut * analyze(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values);
+    const MacroOut * getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId);
+
+    const MacroOut * analyze(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId);
+
+    friend std::wostream & operator<<(std::wostream & out, const CompleteMacroSignature & cms);
 
 };
 
index 78028a7..00cf8ac 100644 (file)
@@ -71,7 +71,7 @@ public:
     Info & share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp);
     Info & clear(const symbol::Symbol & sym, ast::Exp * exp);
     Info & macrodef(ast::Exp * exp);
-    std::vector<TIType> call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp);
+    std::vector<TIType> call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId);
     void addBlock(Block::BlockKind kind, ast::Exp * exp);
     Block * getCurrent();
     void finalizeBlock();
@@ -82,6 +82,7 @@ public:
     void popFunction();
     TIType getType(const symbol::Symbol & sym, const bool global = false);
     Info & getInfo(const symbol::Symbol & sym);
+    void reset();
     friend std::wostream & operator<<(std::wostream & out, const DataManager & dm);
 
     template<typename T>
index 6326f4c..261c26f 100644 (file)
@@ -34,10 +34,12 @@ namespace analysis
 {
 
 struct MacroOut;
+class CompleteMacroSignature;
 
 class FunctionBlock : public Block
 {
 
+    uint64_t functionId;
     std::wstring name;
     std::vector<symbol::Symbol> in;
     std::vector<symbol::Symbol> out;
@@ -57,7 +59,12 @@ class FunctionBlock : public Block
 public:
 
     FunctionBlock(const unsigned int id, Block * parent, ast::Exp * exp);
-    virtual ~FunctionBlock() { }
+
+    virtual ~FunctionBlock()
+       {
+           // we got a clone
+           delete exp;
+       }
 
     inline ConstraintManager & getConstraintManager()
     {
@@ -110,9 +117,24 @@ public:
         rhs = _rhs;
     }
 
-    inline const MPolyConstraintSet & getConstraints() const
+    inline void setFunctionId(const uint64_t id)
+       {
+           functionId = id;
+       }
+
+    inline uint64_t getFunctionId() const
+       {
+           return functionId;
+       }
+
+    inline const MPolyConstraintSet & getVerifiedConstraints() const
+    {
+        return constraintManager.getVerifiedConstraints();
+    }
+
+    inline const ConstraintManager::UnverifiedSet & getUnverifiedConstraints() const
     {
-        return constraintManager.getSet();
+        return constraintManager.getUnverifiedConstraints();
     }
 
     inline const std::set<symbol::Symbol> & getGlobalConstants() const
@@ -156,7 +178,7 @@ public:
     bool addIn(const TITypeSignatureTuple & tuple, const std::vector<GVN::Value *> & values);
     void setGlobals(const tools::SymbolOrdSet & v);
     //TITypeSignatureTuple getGlobals(std::vector<symbol::Symbol> & v);
-    MacroOut getOuts();
+    MacroOut getOuts(CompleteMacroSignature & cms);
     void setInOut(MacroDef * macrodef, const unsigned int rhs, const std::vector<TIType> & _in);
 
     friend std::wostream & operator<<(std::wostream & out, const FunctionBlock & fblock);
index 84267fe..d0a376f 100644 (file)
@@ -102,7 +102,6 @@ public:
 class ExistingMacroDef : public MacroDef
 {
     const std::wstring name;
-    ast::SeqExp * se;
     std::vector<symbol::Symbol> inputs;
     std::vector<symbol::Symbol> outputs;
 
@@ -111,10 +110,7 @@ public:
     ExistingMacroDef(types::Macro & _macro);
     ExistingMacroDef(const ExistingMacroDef & emd);
 
-    ~ExistingMacroDef()
-    {
-        delete se;
-    }
+    ~ExistingMacroDef() { }
 
     ast::SeqExp & getBody();
     const ast::SeqExp & getOriginalBody();
@@ -126,16 +122,12 @@ public:
 
 class DeclaredMacroDef : public MacroDef
 {
-    ast::FunctionDec * dec;
 
 public:
 
     DeclaredMacroDef(ast::FunctionDec * const _dec);
 
-    ~DeclaredMacroDef()
-    {
-        delete dec;
-    }
+    ~DeclaredMacroDef() { }
 
     ast::SeqExp & getBody();
     const ast::SeqExp & getOriginalBody();
diff --git a/scilab/modules/ast/includes/analysis/data/MacroInfo.hxx b/scilab/modules/ast/includes/analysis/data/MacroInfo.hxx
deleted file mode 100644 (file)
index eff3df0..0000000
+++ /dev/null
@@ -1,108 +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 __MACROINFO_HXX__
-#define __MACROINFO_HXX__
-
-#include <iostream>
-#include <map>
-#include <unordered_map>
-#include <vector>
-
-#include "FunctionBlock.hxx"
-
-namespace analysis
-{
-
-struct TITypeTuple
-{
-    std::vector<TIType> types;
-    TITypeTuple(const std::vector<Info> & _types) : types(makeTuple(_types)) { }
-
-    inline static std::vector<TIType> makeTuple(const std::vector<Info> & tuple)
-    {
-        std::vector<TIType> v;
-        v.reserve(tuple.size());
-        for (const auto & i : tuple)
-        {
-            v.emplace_back(i.type);
-        }
-        return v;
-    }
-
-    struct MyHash
-    {
-        inline std::size_t operator()(const TITypeTuple & tuple) const
-        {
-            if (tuple.types.empty())
-            {
-                return 0;
-            }
-            else
-            {
-                std::size_t seed = std::hash<TIType>()(tuple.types.front());
-                for (std::vector<TIType>::const_iterator i = ++tuple.types.begin(), e = tuple.types.end(); i != e; ++i)
-                {
-                    seed = combine(seed, *i);
-                }
-                return seed;
-            }
-        }
-
-        inline static std::size_t combine(const std::size_t seed, const TIType & type)
-        {
-            // it is the way Boost has implemented hash_combine:
-            // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html
-            return seed ^ (std::hash<TIType>()(type) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
-        }
-    };
-};
-
-struct MacroInfo
-{
-    std::map < symbol::Symbol, Info > ;
-    std::vector<symbol::Symbol> globals;
-
-    inline bool isClosure() const
-    {
-        return !globals.empty();
-    }
-};
-
-class PolymorphicMacroCache
-{
-    typedef std::unordered_map<TITypeTuple, MacroInfo, TITypeTuple::MyHash> FunBlockMap;
-    FunctionBlock * fblock;
-    FunBlockMap map;
-
-public:
-
-    PolymorphicMacroCache(FunctionBlock * _fblock) : fblock(_fblock) { }
-
-    const MacroInfo & getOutTypes(const std::vector<Info> & info)
-    {
-        TITypeTuple tuple(info);
-        FunBlockMap::const_iterator i = map.find(tuple);
-        if (i != map.end())
-        {
-            return i->second;
-        }
-        else
-        {
-
-        }
-    }
-};
-
-} // namespace analysis
-
-#endif // __MACROINFO_HXX__
index 8b37559..c0faee7 100644 (file)
 namespace analysis
 {
 
-class AnalysisVisitor;
+    class GVN;
+    class AnalysisVisitor;
 
-class PolymorphicMacroCache
-{
-    typedef std::unordered_map<MacroSignature, CompleteMacroSignature, MacroSignature::Hash, MacroSignature::Eq> MacroSignMap;
-    MacroSignMap signatures;
+    class PolymorphicMacroCache
+    {
+        typedef std::unordered_map<MacroSignature, CompleteMacroSignature, MacroSignature::Hash, MacroSignature::Eq> MacroSignMap;
+       uint64_t id;
+        MacroSignMap signatures;
+        GVN gvn;
+
+    public:
+
+        PolymorphicMacroCache();
+       ~PolymorphicMacroCache();
 
-public:
+        const bool getOutTypes(AnalysisVisitor & visitor, MacroDef * macrodef, std::vector<TIType> & in, std::vector<TIType> & out, uint64_t & functionId);
 
-    PolymorphicMacroCache() { }
+        friend std::wostream & operator<<(std::wostream & out, const PolymorphicMacroCache & pmc);
 
-    const bool getOutTypes(AnalysisVisitor & visitor, MacroDef * macrodef, std::vector<TIType> & in, std::vector<TIType> & out);
+    private:
 
-    static bool getCompleteIn(MacroDef & macrodef, AnalysisVisitor & visitor, const std::vector<TIType> & in, std::vector<TIType> & completeIn);
+        GVN::Value * getValue(const GVN::Value * value, AnalysisVisitor & visitor, const std::vector<const MultivariatePolynomial *> & polys, const int maxVarId) const;
 
-private:
+       static bool getCompleteIn(MacroDef & macrodef, AnalysisVisitor & visitor, const std::vector<TIType> & in, std::vector<TIType> & completeIn);
 
-    GVN::Value * getValue(const GVN::Value * value, AnalysisVisitor & visitor, const std::vector<const MultivariatePolynomial *> & polys, const int maxVarId) const;
-};
+    };
 
 } // namespace analysis
 
index 7ec80e5..7f4e900 100644 (file)
 
 namespace analysis
 {
-struct TITypeTuple
-{
-    std::vector<TIType> types;
+    struct TITypeTuple
+    {
+        std::vector<TIType> types;
 
-    TITypeTuple() { }
+        TITypeTuple() { }
 
-    TITypeTuple(const std::vector<TIType> & _types) : types(_types)
-    {
-        /*types.reserve(_types.size());
-        for (const auto & type : _types)
-        {
-        types.emplace_back(type.type, type.isscalar());
-        }*/
-    }
+        TITypeTuple(const std::vector<TIType> & _types) : types(_types)
+            {
+                /*types.reserve(_types.size());
+                  for (const auto & type : _types)
+                  {
+                  types.emplace_back(type.type, type.isscalar());
+                  }*/
+            }
 
-    inline std::size_t size() const
-    {
-        return types.size();
-    }
+        inline std::size_t size() const
+            {
+                return types.size();
+            }
 
-    inline std::size_t hash() const
-    {
-        if (types.empty())
-        {
-            return 0;
-        }
-        else
-        {
-            std::size_t seed = types.front().hashPureType();
-            for (std::vector<TIType>::const_iterator i = ++types.begin(), e = types.end(); i != e; ++i)
+        inline std::size_t hash() const
             {
-                seed = tools::hash_combine(seed, i->hashPureType());
+                if (types.empty())
+                {
+                    return 0;
+                }
+                else
+                {
+                    std::size_t seed = types.front().hashPureType();
+                    for (std::vector<TIType>::const_iterator i = ++types.begin(), e = types.end(); i != e; ++i)
+                    {
+                        seed = tools::hash_combine(seed, i->hashPureType());
+                    }
+                    return seed;
+                }
             }
-            return seed;
-        }
-    }
 
-    inline bool operator==(const TITypeTuple & R) const
-    {
-        if (types.size() == R.types.size())
-        {
-            for (std::vector<TIType>::const_iterator i = types.begin(), j = R.types.begin(), e = types.end(); i != e; ++i, ++j)
+        inline bool operator==(const TITypeTuple & R) const
             {
-                if (i->type != j->type || i->isscalar() != j->isscalar())
+                if (types.size() == R.types.size())
                 {
-                    return false;
+                    for (std::vector<TIType>::const_iterator i = types.begin(), j = R.types.begin(), e = types.end(); i != e; ++i, ++j)
+                    {
+                        if (i->type != j->type || i->isscalar() != j->isscalar())
+                        {
+                            return false;
+                        }
+                    }
+                    return true;
                 }
+
+                return false;
             }
-            return true;
-        }
 
-        return false;
-    }
+        friend std::wostream & operator<<(std::wostream & out, const TITypeTuple & tuple)
+            {
+                if (tuple.types.empty())
+                {
+                    out << L"[]";
+                }
+                else
+                {
+                    out << L"[";
+                    for (std::vector<TIType>::const_iterator i = tuple.types.begin(), e = std::prev(tuple.types.end()); i != e; ++i)
+                    {
+                        out << *i << L", ";
+                    }
+                    out << tuple.types.back() << L"]";
+                }
+               return out;
+            }
 
-    struct Hash
-    {
-        inline std::size_t operator()(const TITypeTuple & tuple) const
+        struct Hash
         {
-            return tuple.hash();
-        }
-    };
+            inline std::size_t operator()(const TITypeTuple & tuple) const
+                {
+                    return tuple.hash();
+                }
+        };
 
-    struct Eq
-    {
-        inline bool operator()(const TITypeTuple & L, const TITypeTuple & R) const
+        struct Eq
         {
-            return L == R;
-        }
+            inline bool operator()(const TITypeTuple & L, const TITypeTuple & R) const
+                {
+                    return L == R;
+                }
+        };
     };
-};
 
 } // namespace analysis
 
index e54c114..e887277 100644 (file)
@@ -17,6 +17,7 @@
 #include <string>
 #include <set>
 #include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
 #include "InferenceConstraint.hxx"
@@ -30,10 +31,17 @@ namespace analysis
     class EXTERN_AST ConstraintManager
     {
 
+    public:
+
+       typedef std::unordered_set<MPolyConstraintSet, MPolyConstraintSet::Hash, MPolyConstraintSet::Eq> UnverifiedSet;
+
+    private:
+       
         ConstraintManager * parent;
         FunctionBlock * function;
-        MPolyConstraintSet mpConstraints;
+        MPolyConstraintSet verified;
        std::set<symbol::Symbol> constantConstraints;
+       UnverifiedSet unverified;
        
         static std::vector<std::shared_ptr<InferenceConstraint>> generalConstraints;
 
@@ -50,11 +58,16 @@ namespace analysis
             return parent == nullptr;
         }
 
-        inline const MPolyConstraintSet & getSet() const
+        inline const MPolyConstraintSet & getVerifiedConstraints() const
         {
-            return mpConstraints;
+            return verified;
         }
 
+       inline const UnverifiedSet & getUnverifiedConstraints() const
+        {
+            return unverified;
+       }
+
        inline const std::set<symbol::Symbol> & getGlobalConstants() const
        {
             return constantConstraints;
index 8c36fda..d187481 100644 (file)
@@ -14,6 +14,7 @@
 #define __INFERENCE_CONSTRAINT_HXX__
 
 #include <cmath>
+#include <iostream>
 #include <unordered_set>
 #include <vector>
 
@@ -85,7 +86,7 @@ struct PositiveConstraint : public InferenceConstraint
     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const /*override*/;
 };
 
-    struct StrictPositiveConstraint : public InferenceConstraint
+struct StrictPositiveConstraint : public InferenceConstraint
 {
     virtual Result check(GVN & gvn, const std::vector<GVN::Value *> & values) const /*override*/;
     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const /*override*/;
@@ -146,6 +147,11 @@ struct MPolyConstraint : public InferenceConstraint
         }
     }
 
+    inline bool isConstant() const
+       {
+           return poly.isConstant();
+       }
+
     virtual Result check(GVN & gvn, const std::vector<GVN::Value *> & values) const override;
     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
@@ -158,13 +164,20 @@ struct MPolyConstraint : public InferenceConstraint
         }
     };
 
+    inline bool operator==(const MPolyConstraint & R) const
+       {
+           return kind == R.kind && poly == R.poly;
+       }
+    
     struct Eq
     {
         inline bool operator()(const MPolyConstraint & L, const MPolyConstraint & R) const
         {
-            return L.kind == R.kind && L.poly == R.poly;
+            return L == R;
         }
     };
+
+    friend std::wostream & operator<<(std::wostream & out, const MPolyConstraint & mpc);
 };
 
 struct MPolyConstraintSet : public InferenceConstraint
@@ -179,17 +192,26 @@ struct MPolyConstraintSet : public InferenceConstraint
 
     inline void add(MPolyConstraint && mpc)
     {
-        constraints.emplace(std::move(mpc));
+       if (!mpc.isConstant())
+       {
+           constraints.emplace(std::move(mpc));
+       }
     }
 
     inline void add(MultivariatePolynomial && poly, MPolyConstraint::Kind kind)
     {
-        constraints.emplace(std::move(poly), kind);
+       if (!poly.isConstant())
+       {
+           constraints.emplace(std::move(poly), kind);
+       }
     }
 
     inline void add(const MultivariatePolynomial & poly, MPolyConstraint::Kind kind)
     {
-        constraints.emplace(poly, kind);
+       if (!poly.isConstant())
+       {
+           constraints.emplace(poly, kind);
+       }
     }
 
     inline void add(const MPolyConstraintSet & set)
@@ -197,9 +219,42 @@ struct MPolyConstraintSet : public InferenceConstraint
         constraints.insert(set.constraints.begin(), set.constraints.end());
     }
 
+    inline bool empty() const
+       {
+           return constraints.empty();
+       }
+
+    inline std::size_t size() const
+       {
+           return constraints.size();
+       }
+
     virtual Result check(GVN & gvn, const std::vector<GVN::Value *> & values) const override;
     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
+
+    friend std::wostream & operator<<(std::wostream & out, const MPolyConstraintSet & mpcs);
+
+    struct Hash
+    {
+       inline std::size_t operator()(const MPolyConstraintSet & mpcs) const
+           {
+               std::size_t seed = 0;
+               for (const auto & c : mpcs.constraints)
+               {
+                   seed = tools::hash_combine(seed, MPolyConstraint::Hash()(c));
+               }
+               return seed;
+           }
+    };
+
+    struct Eq
+    {
+        inline bool operator()(const MPolyConstraintSet & L, const MPolyConstraintSet & R) const
+        {
+            return L.constraints == R.constraints;
+        }
+    };
 };
 
 
index 7c312ae..9469c44 100644 (file)
@@ -253,7 +253,7 @@ static void printSet(const T & set, std::wostream & out)
 }
 
 template<typename T>
-static void printMap(const T & map, std::wostream & out)
+static void printMap(const T & map, std::wostream & out, const bool newLine = false )
 {
     if (map.empty())
     {
@@ -272,6 +272,10 @@ static void printMap(const T & map, std::wostream & out)
             else
             {
                 out << L",";
+               if (newLine)
+               {
+                   out << L"\n";
+               }
             }
         }
     }
index 8da7348..8665212 100644 (file)
 
 namespace analysis
 {
-AnalysisVisitor::MapSymCall AnalysisVisitor::symscall = AnalysisVisitor::initCalls();//a=1:3;b=2;c=3;testAnalysis("repmat","a","b","c")
+    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;
-}
-
-void AnalysisVisitor::print_info()
-{
-    stop_chrono();
-
-    //std::wcout << getGVN() << std::endl << std::endl; function z=foo(x,y);z=argn(2);endfunction;jit("x=123;y=456;t=foo(x,y)")
-    std::wcerr << L"Analysis: " << *static_cast<Chrono *>(this) << std::endl;
-    //std::wcout << temp << std::endl;
+    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;
+    }
 
-    std::wcerr << dm << std::endl;
 
-    std::wcerr << std::endl;
-}
+    AnalysisVisitor::AnalysisVisitor() : cv(*this), pv(std::wcerr, true, false), logger("/tmp/analysis.log")
+    {
+        start_chrono();
+    }
 
-logging::Logger & AnalysisVisitor::getLogger()
-{
-    return logger;
-}
+    AnalysisVisitor::~AnalysisVisitor() { }
 
-bool AnalysisVisitor::asDouble(types::InternalType * pIT, double & out)
-{
-    if (pIT && pIT->isDouble())
+    void AnalysisVisitor::reset()
     {
-        types::Double * pDbl = static_cast<types::Double *>(pIT);
-        if (!pDbl->isComplex() && pDbl->getSize() == 1)
-        {
-            out = pDbl->get()[0];
-            return true;
-        }
+       _result = Result();
+       dm.reset();
+       multipleLHS.clear();
+       while (!loops.empty())
+       {
+           loops.pop();
+       }
+       start_chrono();
     }
 
-    return false;
-}
+    void AnalysisVisitor::print_info()
+    {
+        stop_chrono();
 
-bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
-{
-    if (e.isDoubleExp())
+        //std::wcout << getGVN() << std::endl << std::endl; function z=foo(x,y);z=argn(2);endfunction;jit("x=123;y=456;t=foo(x,y)")
+        std::wcerr << L"Analysis: " << *static_cast<Chrono *>(this) << std::endl;
+        //std::wcout << temp << std::endl;
+
+        std::wcerr << dm << std::endl;
+       std::wcerr << pmc << std::endl;
+
+        std::wcerr << std::endl;
+    }
+
+    logging::Logger & AnalysisVisitor::getLogger()
     {
-        out = static_cast<ast::DoubleExp &>(e).getValue();
-        return true;
+        return logger;
     }
-    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;
@@ -152,70 +173,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:
@@ -224,80 +245,60 @@ 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))
+    bool AnalysisVisitor::asDoubleMatrix(ast::Exp & e, types::Double *& data)
     {
-        ast::ExecVisitor exec;
-        e.accept(exec);
-        types::InternalType * pIT = exec.getResult();
-        // TODO : handle complex case
-        if (pIT && pIT->isDouble() && !pIT->getAs<types::Double>()->isComplex())
+        if (isDoubleConstant(e))
         {
-            pIT->IncreaseRef();
-            data = static_cast<types::Double *>(pIT);
+            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);
 
-            return true;
+                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)
-{
-    std::vector<Result> resargs;
-    std::vector<TIType> vargs;
-    vargs.reserve(args.size());
-    resargs.reserve(args.size());
-
-    for (auto arg : args)
-    {
-        arg->accept(*this);
-        resargs.push_back(getResult());
-        vargs.push_back(getResult().getType());
+        return false;
     }
 
-    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)
+    void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, const ast::exps_t & args)
     {
-        multipleLHS.clear();
-        multipleLHS.reserve(out.size());
-        for (const auto & type : out)
-        {
-            const int tempId = getDM().getTmpId(type, false);
-            multipleLHS.emplace_back(type, tempId);
-        }
+        std::vector<Result> resargs;
+        std::vector<TIType> vargs;
+        vargs.reserve(args.size());
+        resargs.reserve(args.size());
 
-        auto i = args.begin();
-        for (const auto & resarg : resargs)
+        for (auto arg : args)
         {
-            getDM().releaseTmp(resarg.getTempId(), *i);
-            ++i;
+            arg->accept(*this);
+            resargs.push_back(getResult());
+            vargs.push_back(getResult().getType());
         }
-    }
-    else if (lhs == 1)
-    {
-        int tempId = -1;
-        if (resargs.size() == 1)
+
+        const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
+       uint64_t functionId = 0;
+        std::vector<TIType> out = getDM().call(*this, lhs, sym, vargs, &e, functionId);
+        if (lhs > 1)
         {
-            const int id = resargs.back().getTempId();
-            if (id != -1 && Checkers::isElementWise(name) && out[0] == resargs.back().getType())
+            multipleLHS.clear();
+            multipleLHS.reserve(out.size());
+            for (const auto & type : out)
             {
-                tempId = id;
+                const int tempId = getDM().getTmpId(type, false);
+                multipleLHS.emplace_back(type, tempId);
             }
-        }
-        if (tempId == -1)
-        {
-            tempId = getDM().getTmpId(out[0], false);
+
             auto i = args.begin();
             for (const auto & resarg : resargs)
             {
@@ -305,154 +306,175 @@ void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned i
                 ++i;
             }
         }
+        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);
+                auto i = args.begin();
+                for (const auto & resarg : resargs)
+                {
+                    getDM().releaseTmp(resarg.getTempId(), *i);
+                    ++i;
+                }
+            }
 
-        e.getDecorator().res = Result(out[0], tempId);
-        e.getDecorator().setCall(name, vargs);
-        setResult(e.getDecorator().res);
+            e.getDecorator().res = Result(out[0], tempId, functionId);
+            e.getDecorator().setCall(name, vargs);
+            setResult(e.getDecorator().res);
+        }
     }
-}
 
-int AnalysisVisitor::getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR, ast::Exp * Lexp, ast::Exp * Rexp)
-{
-    int tempId = -1;
-    if (resT.isknown() && resT.ismatrix())
+    int AnalysisVisitor::getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR, ast::Exp * Lexp, ast::Exp * Rexp)
     {
-        if (LR.isTemp() || RR.isTemp())
+        int tempId = -1;
+        if (resT.isknown() && resT.ismatrix())
         {
-            const int Lid = LR.getTempId();
-            const int Rid = RR.getTempId();
-            const TIType & LT = LR.getType();
-            const TIType & RT = RR.getType();
-
-            if (LT.isscalar())
+            if (LR.isTemp() || RR.isTemp())
             {
-                if (RT.isscalar())
+                const int Lid = LR.getTempId();
+                const int Rid = RR.getTempId();
+                const TIType & LT = LR.getType();
+                const TIType & RT = RR.getType();
+
+                if (LT.isscalar())
                 {
-                    if (Lid == -1)
+                    if (RT.isscalar())
                     {
-                        if (resT == LT)
+                        if (Lid == -1)
                         {
-                            tempId = Rid;
+                            if (resT == LT)
+                            {
+                                tempId = Rid;
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
                         }
                         else
                         {
-                            tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Rid, Rexp);
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
+                            else if (Rid != -1 && resT == RT)
+                            {
+                                tempId = Rid;
+                                getDM().releaseTmp(Lid, Lexp);
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid, Lexp);
+                            }
                         }
                     }
                     else
                     {
-                        if (resT == LT)
-                        {
-                            tempId = Lid;
-                            getDM().releaseTmp(Rid, Rexp);
-                        }
-                        else if (Rid != -1 && resT == RT)
-                        {
-                            tempId = Rid;
-                            getDM().releaseTmp(Lid, Lexp);
-                        }
-                        else
-                        {
-                            tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Lid, Lexp);
-                        }
-                    }
-                }
-                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, Rexp);
-                        }
-                        else
+                        if (Rid == -1)
                         {
                             tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Rid, Rexp);
-                        }
-                    }
-                    getDM().releaseTmp(Lid, Lexp);
-                }
-            }
-            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, Lexp);
                         }
                         else
                         {
-                            tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Lid, Lexp);
+                            if (resT == RT)
+                            {
+                                tempId = Rid;
+                            }
+                            else if (Lid != -1 && resT == LT)
+                            {
+                                tempId = Lid;
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
                         }
+                        getDM().releaseTmp(Lid, Lexp);
                     }
-                    getDM().releaseTmp(Rid, Rexp);
                 }
                 else
                 {
-                    if (Rid == -1)
+                    if (RT.isscalar())
                     {
-                        if (resT == LT)
+                        if (Lid == -1)
                         {
-                            tempId = Lid;
+                            tempId = getDM().getTmpId(resT, false);
                         }
                         else
                         {
-                            tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Lid, Lexp);
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                            }
+                            else if (Rid != -1 && resT == RT)
+                            {
+                                tempId = Rid;
+                                getDM().releaseTmp(Lid, Lexp);
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid, Lexp);
+                            }
                         }
+                        getDM().releaseTmp(Rid, Rexp);
                     }
                     else
                     {
-                        if (resT == RT)
+                        if (Rid == -1)
                         {
-                            tempId = Rid;
-                        }
-                        else if (Lid != -1 && resT == LT)
-                        {
-                            tempId = Lid;
-                            getDM().releaseTmp(Rid, Rexp);
+                            if (resT == LT)
+                            {
+                                tempId = Lid;
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Lid, Lexp);
+                            }
                         }
                         else
                         {
-                            tempId = getDM().getTmpId(resT, false);
-                            getDM().releaseTmp(Rid, Rexp);
+                            if (resT == RT)
+                            {
+                                tempId = Rid;
+                            }
+                            else if (Lid != -1 && resT == LT)
+                            {
+                                tempId = Lid;
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
+                            else
+                            {
+                                tempId = getDM().getTmpId(resT, false);
+                                getDM().releaseTmp(Rid, Rexp);
+                            }
+                            getDM().releaseTmp(Lid, Lexp);
                         }
-                        getDM().releaseTmp(Lid, Lexp);
                     }
                 }
             }
+            else
+            {
+                tempId = getDM().getTmpId(resT, false);
+            }
         }
-        else
-        {
-            tempId = getDM().getTmpId(resT, false);
-        }
-    }
 
-    return tempId;
-}
+        return tempId;
+    }
 }
index b59b061..9c6c9a6 100644 (file)
@@ -280,7 +280,7 @@ Info & Block::addMacroDef(ast::FunctionDec * dec)
     return i;
 }
 
-std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp)
+    std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
 {
     tools::SymbolMap<Info>::iterator it;
     Block * block = getDefBlock(sym, it, false);
@@ -319,19 +319,19 @@ std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int
         {
             if (pIT)
             {
-                visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
+                visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out, functionId);
             }
             else
             {
                 if (it->second.exp && it->second.exp->isFunctionDec())
                 {
                     DeclaredMacroDef macrodef(static_cast<ast::FunctionDec *>(it->second.exp));
-                    visitor.getPMC().getOutTypes(visitor, &macrodef, in, out);
+                    visitor.getPMC().getOutTypes(visitor, &macrodef, in, out, functionId);
                 }
                 else
                 {
                     DataManager::getSymInScilabContext(getGVN(), sym, pIT);
-                    visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
+                    visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out, functionId);
                 }
             }
             break;
@@ -339,7 +339,7 @@ std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int
         case TIType::MACROFILE:
         {
             DataManager::getSymInScilabContext(getGVN(), sym, pIT);
-            visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::MacroFile *>(pIT)->getMacro()), in, out);
+            visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::MacroFile *>(pIT)->getMacro()), in, out, functionId);
             break;
         }
         default:
index e2cee64..66d2f38 100644 (file)
@@ -30,12 +30,13 @@ bool CeilAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
             const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
             const std::wstring & name = sym.getName();
             std::vector<TIType> vargs({ Rtype });
-            std::vector<TIType> out = visitor.getDM().call(visitor, lhs, sym, vargs, &e);
+           uint64_t functionId = 0;
+            std::vector<TIType> out = visitor.getDM().call(visitor, lhs, sym, vargs, &e, functionId);
             if (Rtype.isintegral())
             {
                 const ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getName());
 
-                e.getDecorator().res = Result(Rtype, R.getTempId());
+                e.getDecorator().res = Result(Rtype, R.getTempId(), functionId);
                 e.getDecorator().setCall(name, vargs);
                 visitor.setResult(e.getDecorator().res);
 
@@ -44,7 +45,7 @@ bool CeilAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as
 
             if (out[0].type != TIType::UNKNOWN)
             {
-                e.getDecorator().res = Result(Rtype, R.getTempId());
+                e.getDecorator().res = Result(Rtype, R.getTempId(), functionId);
                 e.getDecorator().setCall(name, vargs);
                 visitor.setResult(e.getDecorator().res);
 
index 1cb817d..7fa1e53 100644 (file)
 
 namespace analysis
 {
-const MacroOut * CompleteMacroSignature::getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values)
+    const MacroOut * CompleteMacroSignature::getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId)
 {
     for (const auto & mpcmo : outMap)
     {
-        if (mpcmo.mpConstraints.check(visitor.getGVN(), values) == InferenceConstraint::Result::RESULT_TRUE && ConstraintManager::checkGlobalConstants(mpcmo.globalConstants))
+        if (mpcmo.verified.check(visitor.getGVN(), values) == InferenceConstraint::RESULT_TRUE && ConstraintManager::checkGlobalConstants(mpcmo.globalConstants))
         {
+           for (const auto & set : mpcmo.unverified)
+           {
+               if (set.check(visitor.getGVN(), values) != InferenceConstraint::RESULT_FALSE)
+               {
+                   return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
+               }
+           }
+           functionId = mpcmo.id;
             return &mpcmo.out;
         }
     }
 
-    return analyze(visitor, signature, macrodef, dm, rhs, in, values);
+    return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
 }
 
-const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values)
+const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId)
 {
     if (signature.lhs <= macrodef->getLhs())
     {
@@ -50,14 +58,35 @@ const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, cons
 
         fblock.getExp()->accept(visitor);
         dm.finalizeBlock();
-        std::wcerr << fblock << std::endl;
+        //std::wcerr << fblock << std::endl;
         visitor.emitFunctionBlock(fblock);
-        outMap.emplace_back(fblock.getConstraints(), fblock.getGlobalConstants(), fblock.getOuts());
+        const auto p = outMap.emplace(id++, fblock.getVerifiedConstraints(), fblock.getUnverifiedConstraints(), fblock.getGlobalConstants(), fblock.getOuts(*this));
+       fblock.setFunctionId(p.first->id);
+       functionId = p.first->id;
 
-        return &outMap.back().out;
+       //std::wcerr << *this << std::endl;
+       
+        return &p.first->out;
     }
 
     return nullptr;
 }
 
+    std::wostream & operator<<(std::wostream & out, const CompleteMacroSignature & cms)
+    {
+       out << L"Complete Macro Cache:\n";
+       for (const auto & mpcmo : cms.outMap)
+       {
+           out << L" * Verified constraints: " << mpcmo.verified << L"\n"
+               << L" * Unverified constraints: ";
+           tools::printSet(mpcmo.unverified, out);
+           out << L"\n"
+               << L" * Globals: ";
+           tools::printSet(mpcmo.globalConstants, out);
+           out << L"\n"
+               << L"   => " << mpcmo.out.tuple << L"\n";
+       }
+       return out;
+    }
+
 } // namespace analysis
index 3fedae7..051eaa3 100644 (file)
@@ -53,24 +53,38 @@ bool ConstraintManager::check(const MPolyConstraintSet & set, const std::vector<
     InferenceConstraint::Result res = set.check((parent && parent->function) ? parent->function->getGVN() : function->getGVN(), values);
     switch (res)
     {
-        case InferenceConstraint::Result::RESULT_TRUE:
+        case InferenceConstraint::RESULT_TRUE:
         {
-            mpConstraints.add(set);
-            set.applyConstraints(values);
+           if (!set.empty())
+           {
+               verified.add(set);
+               set.applyConstraints(values);
+           }
             return true;
         }
-        case InferenceConstraint::Result::RESULT_FALSE:
+        case InferenceConstraint::RESULT_FALSE:
+           if (!set.empty())
+           {
+               unverified.emplace(set);
+           }
             return false;
-        case InferenceConstraint::Result::RESULT_DUNNO:
+        case InferenceConstraint::RESULT_DUNNO:
         {
             if (parent && parent->function)
             {
                 const bool ret = parent->check(set.getMPConstraints(values), parent->function->getInValues());
-                if (ret)
-                {
-                    mpConstraints.add(set);
-                    set.applyConstraints(values);
-                }
+               if (!set.empty())
+               {
+                   if (ret)
+                   {
+                       verified.add(set);
+                       set.applyConstraints(values);
+                   }
+                   else
+                   {
+                       unverified.emplace(set);
+                   }
+               }
                 return ret;
             }
             else
@@ -87,27 +101,43 @@ bool ConstraintManager::check(Kind kind, const std::vector<GVN::Value *> & value
     {
         const InferenceConstraint & ic = *generalConstraints[kind];
         InferenceConstraint::Result res = ic.check(function->getGVN(), values);
+       const MPolyConstraintSet set = ic.getMPConstraints(values); 
         //std::wcerr << "DEBUG2=" << res << std::endl;
 
         switch (res)
         {
-            case InferenceConstraint::Result::RESULT_TRUE:
+            case InferenceConstraint::RESULT_TRUE:
             {
-                mpConstraints.add(ic.getMPConstraints(values));
-                ic.applyConstraints(values);
+               if (!set.empty())
+               {
+                   verified.add(set);
+                   ic.applyConstraints(values);
+               }
                 return true;
             }
-            case InferenceConstraint::Result::RESULT_FALSE:
+            case InferenceConstraint::RESULT_FALSE:
+               if (!set.empty())
+               {
+                   unverified.emplace(set);
+               }
                 return false;
-            case InferenceConstraint::Result::RESULT_DUNNO:
+            case InferenceConstraint::RESULT_DUNNO:
             {
                 MPolyConstraintSet set = ic.getMPConstraints(values);
                 const bool ret = check(set, function->getInValues());
-                if (ret)
-                {
-                    mpConstraints.add(set);
-                    ic.applyConstraints(values);
-                }
+
+               if (!set.empty())
+               {
+                   if (ret)
+                   {
+                       verified.add(set);
+                       ic.applyConstraints(values);
+                   }
+                   else
+                   {
+                       unverified.emplace(set);
+                   }
+               }
                 return ret;
             }
         }
index 0352c93..02598da 100644 (file)
 namespace analysis
 {
 
-DataManager::DataManager() : id(0)
-{
-    current = root = new Block(this);
-}
+    DataManager::DataManager() : id(0)
+    {
+        current = root = new Block(this);
+    }
 
-DataManager::~DataManager()
-{
-    for (const auto d : data)
+    DataManager::~DataManager()
     {
-        delete d;
+        for (const auto d : data)
+        {
+            delete d;
+        }
+        delete root;
+        for (const auto & p : macroDefCache)
+        {
+            delete p.second;
+        }
     }
-    delete root;
-    for (const auto & p : macroDefCache)
+
+    void DataManager::reset()
     {
-        delete p.second;
+       for (const auto d : data)
+        {
+            delete d;
+        }
+       data.clear();
+       delete root;
+        current = root = new Block(this);
+       globals.clear();
+       while (!callStack.empty())
+       {
+           callStack.pop();
+       }
+       for (const auto & p : macroDefCache)
+        {
+            delete p.second;
+        }
+       macroDefCache.clear();
     }
-}
 
-GVN & DataManager::getGVN()
-{
-    return current->getGVN();
-}
+    GVN & DataManager::getGVN()
+    {
+        return current->getGVN();
+    }
 
-GVN & DataManager::getDefaultGVN()
-{
-    return gvn;
-}
+    GVN & DataManager::getDefaultGVN()
+    {
+        return gvn;
+    }
 
-MacroDef * DataManager::getMacroDef(types::Macro * macro)
-{
-    auto i = macroDefCache.find(macro);
-    if (i == macroDefCache.end())
+    MacroDef * DataManager::getMacroDef(types::Macro * macro)
     {
-        i = macroDefCache.emplace(macro, new ExistingMacroDef(*macro)).first;
+        auto i = macroDefCache.find(macro);
+        if (i == macroDefCache.end())
+        {
+            i = macroDefCache.emplace(macro, new ExistingMacroDef(*macro)).first;
+        }
+        return i->second;
     }
-    return i->second;
-}
 
-void DataManager::addGlobal(const symbol::Symbol & sym)
-{
-    globals.emplace(sym);
-}
+    void DataManager::addGlobal(const symbol::Symbol & sym)
+    {
+        globals.emplace(sym);
+    }
 
-void DataManager::registerData(Data * _data, int line, char * file)
-{
-    if (_data)
+    void DataManager::registerData(Data * _data, int line, char * file)
     {
-        /*              bool ok = true;
-                        for (const auto d : data)
-                        {
-                        if (d == _data)
-                        {
-                        ok =  false;
-                        break;
-                        }
-                        }
-
-                        std::cout << "ptr added=" << _data << " line:" << line << " file:" << file << " doubloon:" << ok << std::endl;
-        */
-        data.push_back(_data);
+        if (_data)
+        {
+            /*              bool ok = true;
+                            for (const auto d : data)
+                            {
+                            if (d == _data)
+                            {
+                            ok =  false;
+                            break;
+                            }
+                            }
+
+                            std::cout << "ptr added=" << _data << " line:" << line << " file:" << file << " doubloon:" << ok << std::endl;
+            */
+            data.push_back(_data);
+        }
     }
-}
 
-int DataManager::getTmpId(const TIType & type, const bool isAnInt)
-{
-    return current->getTmpId(type, isAnInt);
-}
+    int DataManager::getTmpId(const TIType & type, const bool isAnInt)
+    {
+        return current->getTmpId(type, isAnInt);
+    }
 
-void DataManager::releaseTmp(const int id, ast::Exp * exp)
-{
-    current->releaseTmp(id, exp);
-}
+    void DataManager::releaseTmp(const int id, ast::Exp * exp)
+    {
+        current->releaseTmp(id, exp);
+    }
 
-Info & DataManager::read(const symbol::Symbol & sym, ast::Exp * exp)
-{
-    return current->addRead(sym, exp);
-}
+    Info & DataManager::read(const symbol::Symbol & sym, ast::Exp * exp)
+    {
+        return current->addRead(sym, exp);
+    }
 
-Info & DataManager::write(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
-{
-    return current->addWrite(sym, Rtype, exp);
-}
+    Info & DataManager::write(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
+    {
+        return current->addWrite(sym, Rtype, exp);
+    }
 
-Info & DataManager::define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
-{
-    return current->addDefine(sym, Rtype, isAnInt, exp);
-}
+    Info & DataManager::define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
+    {
+        return current->addDefine(sym, Rtype, isAnInt, exp);
+    }
 
-Info & DataManager::share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
-{
-    return current->addShare(Lsym, Rsym, Rtype, exp);
-}
+    Info & DataManager::share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
+    {
+        return current->addShare(Lsym, Rsym, Rtype, exp);
+    }
 
-Info & DataManager::clear(const symbol::Symbol & sym, ast::Exp * exp)
-{
-    return current->addClear(sym, exp);
-}
+    Info & DataManager::clear(const symbol::Symbol & sym, ast::Exp * exp)
+    {
+        return current->addClear(sym, exp);
+    }
 
-Info & DataManager::macrodef(ast::Exp * exp)
-{
-    return current->addMacroDef(static_cast<ast::FunctionDec *>(exp));
-}
+    Info & DataManager::macrodef(ast::Exp * exp)
+    {
+        return current->addMacroDef(static_cast<ast::FunctionDec *>(exp));
+    }
 
-std::vector<TIType> DataManager::call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp)
-{
-    return current->addCall(visitor, lhs, sym, in, callexp);
-}
+    std::vector<TIType> DataManager::call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
+    {
+        return current->addCall(visitor, lhs, sym, in, callexp, functionId);
+    }
 
-void DataManager::addBlock(Block::BlockKind kind, ast::Exp * exp)
-{
-    current = current->addBlock(++id, kind, exp);
-}
+    void DataManager::addBlock(Block::BlockKind kind, ast::Exp * exp)
+    {
+        current = current->addBlock(++id, kind, exp);
+    }
 
-Block * DataManager::getCurrent()
-{
-    return current;
-}
+    Block * DataManager::getCurrent()
+    {
+        return current;
+    }
 
-void DataManager::finalizeBlock()
-{
+    void DataManager::finalizeBlock()
+    {
 #ifndef DEBUG_DATAMANAGER
-    current->finalize();
+        current->finalize();
 #endif
-    current = current->parent;
-}
+        current = current->parent;
+    }
 
-bool DataManager::requiresAnotherTrip()
-{
-    return current->requiresAnotherTrip();
-}
+    bool DataManager::requiresAnotherTrip()
+    {
+        return current->requiresAnotherTrip();
+    }
 
-void DataManager::pushFunction(FunctionBlock * fblock)
-{
-    callStack.push(fblock);
-}
+    void DataManager::pushFunction(FunctionBlock * fblock)
+    {
+        callStack.push(fblock);
+    }
 
-FunctionBlock * DataManager::poptopFunction()
-{
-    FunctionBlock * fblock = callStack.top();
-    callStack.pop();
-    return fblock;
-}
+    FunctionBlock * DataManager::poptopFunction()
+    {
+        FunctionBlock * fblock = callStack.top();
+        callStack.pop();
+        return fblock;
+    }
 
-FunctionBlock * DataManager::topFunction()
-{
-    if (callStack.empty())
+    FunctionBlock * DataManager::topFunction()
     {
-        return nullptr;
+        if (callStack.empty())
+        {
+            return nullptr;
+        }
+        return callStack.top();
     }
-    return callStack.top();
-}
 
-void DataManager::popFunction()
-{
-    callStack.pop();
-}
+    void DataManager::popFunction()
+    {
+        callStack.pop();
+    }
 
-TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists)
-{
-    types::InternalType * pIT;
-    return getSymInScilabContext(gvn, sym, exists, pIT);
-}
+    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists)
+    {
+        types::InternalType * pIT;
+        return getSymInScilabContext(gvn, sym, exists, pIT);
+    }
 
-TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, types::InternalType *& pIT)
-{
-    bool exists;
-    return getSymInScilabContext(gvn, sym, exists, pIT);
-}
+    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, types::InternalType *& pIT)
+    {
+        bool exists;
+        return getSymInScilabContext(gvn, sym, exists, pIT);
+    }
 
-TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists, types::InternalType *& pIT)
-{
-    pIT = symbol::Context::getInstance()->get(sym);
-    if (pIT)
+    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists, types::InternalType *& pIT)
     {
-        exists = true;
-        if (pIT->isGenericType())
+        pIT = symbol::Context::getInstance()->get(sym);
+        if (pIT)
         {
-            types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
-            switch (pIT->getType())
+            exists = true;
+            if (pIT->isGenericType())
             {
+                types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
+                switch (pIT->getType())
+                {
                 case types::InternalType::ScilabInt8:
                     return TIType(gvn, TIType::Type::INT8, pGT->getRows(), pGT->getCols());
                 case types::InternalType::ScilabUInt8:
@@ -242,12 +263,12 @@ TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym,
                     return TIType(gvn, TIType::Type::SPARSE, pGT->getRows(), pGT->getCols());
                 default:
                     return TIType(gvn, TIType::Type::UNKNOWN, pGT->getRows(), pGT->getCols());
+                }
             }
-        }
-        else if (pIT->isCallable())
-        {
-            switch (pIT->getType())
+            else if (pIT->isCallable())
             {
+                switch (pIT->getType())
+                {
                 case types::InternalType::ScilabFunction:
                     return TIType(gvn, TIType::Type::FUNCTION);
                 case types::InternalType::ScilabMacro:
@@ -256,52 +277,52 @@ TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym,
                     return TIType(gvn, TIType::Type::MACROFILE);
                 case types::InternalType::ScilabLibrary:
                     return TIType(gvn, TIType::Type::LIBRARY);
+                }
             }
         }
-    }
-
-    exists = false;
-    return TIType(gvn);
-}
 
-TIType DataManager::getType(const symbol::Symbol & sym, const bool global)
-{
-    Block * parent = getCurrent();
-    tools::SymbolMap<Info>::iterator it;
-    Block * block = parent->getDefBlock(sym, it, global);
-    if (block)
-    {
-        return it->second.type;
+        exists = false;
+        return TIType(gvn);
     }
-    else
+
+    TIType DataManager::getType(const symbol::Symbol & sym, const bool global)
     {
-        bool exists;
-        return DataManager::getSymInScilabContext(getGVN(), sym, exists);
+        Block * parent = getCurrent();
+        tools::SymbolMap<Info>::iterator it;
+        Block * block = parent->getDefBlock(sym, it, global);
+        if (block)
+        {
+            return it->second.type;
+        }
+        else
+        {
+            bool exists;
+            return DataManager::getSymInScilabContext(getGVN(), sym, exists);
+        }
     }
-}
 
-Info & DataManager::getInfo(const symbol::Symbol & sym)
-{
-    tools::SymbolMap<Info>::iterator it;
-    Block * block = current->getDefBlock(sym, it, false);
-    if (block)
+    Info & DataManager::getInfo(const symbol::Symbol & sym)
     {
-        return it->second;
-    }
+        tools::SymbolMap<Info>::iterator it;
+        Block * block = current->getDefBlock(sym, it, false);
+        if (block)
+        {
+            return it->second;
+        }
 
-    // The sym is not in this DataManager... try in the Scilab's context
-    return current->setDefaultData(sym);
-}
+        // The sym is not in this DataManager... try in the Scilab's context
+        return current->setDefaultData(sym);
+    }
 
-std::wostream & operator<<(std::wostream & out, const DataManager & dm)
-{
-    out << L"DataManager:" << std::endl
-        << L"Globals: ";
+    std::wostream & operator<<(std::wostream & out, const DataManager & dm)
+    {
+        out << L"DataManager:" << std::endl
+            << L"Globals: ";
 
-    tools::printSet(dm.globals, out);
-    out << std::endl << *dm.root;
+        tools::printSet(dm.globals, out);
+        out << std::endl << *dm.root;
 
-    return out;
-}
+        return out;
+    }
 
 } // namespace analysis
index 7e7b3c0..0688caa 100644 (file)
@@ -21,7 +21,7 @@
 namespace analysis
 {
 
-FunctionBlock::FunctionBlock(const unsigned int id, Block * parent, ast::Exp * exp) : Block(id, parent, exp), loopAnalyzer(exp), constraintManager(*this, dm->topFunction()), lhs(0), rhs(0), maxVarId(0)
+FunctionBlock::FunctionBlock(const unsigned int id, Block * parent, ast::Exp * exp) : Block(id, parent, exp), functionId(0), loopAnalyzer(exp), constraintManager(*this, dm->topFunction()), lhs(0), rhs(0), maxVarId(0)
 {
     gvn = &fgvn;
     dm->pushFunction(this);
@@ -91,33 +91,40 @@ void FunctionBlock::setGlobals(const tools::SymbolOrdSet & v)
         return tuple;
     }
 */
-MacroOut FunctionBlock::getOuts()
+MacroOut FunctionBlock::getOuts(CompleteMacroSignature & cms)
 {
     MacroOut mo;
     mo.maxVarId = maxVarId;
     std::vector<TIType> & v = mo.tuple.types;
     v.reserve(lhs);
     unsigned int i = 0;
+    GVN & cmsGVN = cms.getGVN();
     for (std::vector<symbol::Symbol>::const_iterator s = out.begin(); i < lhs; ++i, ++s)
     {
         tools::SymbolMap<Info>::iterator it;
         Block * block = getDefBlock(*s, it, false);
         if (block == this)
         {
-            v.emplace_back(it->second.type);
+           const TIType & ty = it->second.type;
+           const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
+           const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
+            v.emplace_back(TIType(cmsGVN, ty.type, rows, cols));
         }
         else
         {
             addGlobal(*s);
             if (block)
             {
-                v.emplace_back(it->second.type);
+               const TIType & ty = it->second.type;
+               const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
+               const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
+               v.emplace_back(TIType(cmsGVN, ty.type, rows, cols));
             }
             else
             {
                 // TODO: if exists is false then it is an error
                 bool exists;
-                v.emplace_back(DataManager::getSymInScilabContext(fgvn, *s, exists));
+                v.emplace_back(DataManager::getSymInScilabContext(cmsGVN, *s, exists));
             }
         }
     }
index 546ddc9..c246498 100644 (file)
@@ -86,10 +86,11 @@ namespace analysis
         }
         else
         {
-            GVN::Value * val = getValue();
-            insertValue(mp, *val);
+           list.emplace_back(current++);
+           Value & val = list.back();
+            insertValue(mp, val);
 
-            return val;
+            return &val;
         }
     }
 
index bd01aaf..4c4fe5f 100644 (file)
@@ -458,4 +458,32 @@ MPolyConstraintSet ValidRangeConstraint::getMPConstraints(const std::vector<GVN:
 
     return set;
 }
+
+std::wostream & operator<<(std::wostream & out, const MPolyConstraint & mpc)
+{
+    out << mpc.poly;
+    switch (mpc.kind)
+    {
+        case MPolyConstraint::Kind::EQ0:
+            out << L" = 0";
+            break;
+        case MPolyConstraint::Kind::NEQ0:
+            out << L" != 0";
+            break;
+        case MPolyConstraint::Kind::GT0:
+            out << L" > 0";
+            break;
+        case MPolyConstraint::Kind::GEQ0:
+            out << L" >= 0";
+            break;
+    }
+
+    return out;
+}
+
+std::wostream & operator<<(std::wostream & out, const MPolyConstraintSet & mpcs)
+{
+    tools::printSet(mpcs.constraints, out);
+    return out;
+}
 }
index 29a5c4d..1d72522 100644 (file)
 
 namespace analysis
 {
-ExistingMacroDef::ExistingMacroDef(types::Macro & _macro) : MacroDef(_macro.getOutputs()->size(), _macro.getInputs()->size(), _macro.getBody()), name(_macro.getName()), se(nullptr), inputs(MacroDef::asVector(_macro.getInputs())), outputs(MacroDef::asVector(_macro.getOutputs()))
+ExistingMacroDef::ExistingMacroDef(types::Macro & _macro) : MacroDef(_macro.getOutputs()->size(), _macro.getInputs()->size(), _macro.getBody()), name(_macro.getName()), inputs(MacroDef::asVector(_macro.getInputs())), outputs(MacroDef::asVector(_macro.getOutputs()))
 {
     GlobalsCollector::collect(*this);
 }
 
-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)
+ExistingMacroDef::ExistingMacroDef(const ExistingMacroDef & emd) : MacroDef(emd.inputs.size(), emd.outputs.size(), emd.original), name(emd.name), inputs(emd.inputs), outputs(emd.outputs)
 {
     GlobalsCollector::collect(*this);
 }
 
 ast::SeqExp & ExistingMacroDef::getBody()
 {
-    if (!se)
-    {
-        se = static_cast<ast::SeqExp *>(original)->clone();
-    }
-    return *se;
+    return *static_cast<ast::SeqExp *>(original)->clone();
 }
 
 const ast::SeqExp & ExistingMacroDef::getOriginalBody()
@@ -59,18 +55,14 @@ MacroDef * ExistingMacroDef::clone() const
     return new ExistingMacroDef(*this);
 }
 
-DeclaredMacroDef::DeclaredMacroDef(ast::FunctionDec * const _dec) : MacroDef(_dec->getReturns().getVars().size(), _dec->getArgs().getVars().size(), _dec), dec(nullptr)
+DeclaredMacroDef::DeclaredMacroDef(ast::FunctionDec * const _dec) : MacroDef(_dec->getReturns().getVars().size(), _dec->getArgs().getVars().size(), _dec)
 {
     GlobalsCollector::collect(*this);
 }
 
 ast::SeqExp & DeclaredMacroDef::getBody()
 {
-    if (!dec)
-    {
-        dec = static_cast<ast::FunctionDec *>(original)->clone();
-    }
-    return static_cast<ast::SeqExp &>(dec->getBody());
+    return *static_cast<ast::SeqExp *>(static_cast<ast::FunctionDec *>(original)->getBody().clone());
 }
 
 const ast::SeqExp & DeclaredMacroDef::getOriginalBody()
@@ -95,7 +87,7 @@ std::vector<symbol::Symbol> DeclaredMacroDef::getOut()
 
 MacroDef * DeclaredMacroDef::clone() const
 {
-    return new DeclaredMacroDef(dec ? dec : static_cast<ast::FunctionDec *>(original));
+    return new DeclaredMacroDef(static_cast<ast::FunctionDec *>(original));
 }
 
 } // namespace analysis
index beaaab6..0440d10 100644 (file)
@@ -140,21 +140,49 @@ namespace analysis
     const std::wstring MultivariateMonomial::print(const std::map<uint64_t, std::wstring> & vars) const
     {
         std::wostringstream wos;
-        wos << coeff;
-        for (const auto & ve : monomial)
-        {
-            wos << L"*" << ve.print(vars);
-        }
+       if (coeff == 1)
+       {
+           if (!monomial.empty())
+           {
+               wos << monomial.begin()->print(vars);
+               for (auto i = std::next(monomial.begin()), e = monomial.end(); i != e; ++i)
+               {
+                   wos << L"*" << i->print(vars);
+               }
+           }
+       }
+       else
+       {
+           wos << coeff;
+           for (const auto & ve : monomial)
+           {
+               wos << L"*" << ve.print(vars);
+           }
+       }
         return wos.str();
     }
 
     std::wostream & operator<<(std::wostream & out, const MultivariateMonomial & m)
     {
-        out << m.coeff;
-        for (const auto & ve : m.monomial)
-        {
-            out << L"*" << ve;
-        }
+       if (m.coeff == 1)
+       {
+           if (!m.monomial.empty())
+           {
+               out << *m.monomial.begin();
+               for (auto i = std::next(m.monomial.begin()), e = m.monomial.end(); i != e; ++i)
+               {
+                   out << L"*" << *i;
+               }
+           }
+       }
+       else
+       {
+           out << m.coeff;
+           for (const auto & ve : m.monomial)
+           {
+               out << L"*" << ve;
+           }
+       }
         return out;
     }
 
index b2f3005..dccbba3 100644 (file)
 
 namespace analysis
 {
-const bool PolymorphicMacroCache::getOutTypes(AnalysisVisitor & visitor, MacroDef * macrodef, std::vector<TIType> & in, std::vector<TIType> & out)
-{
-
-    // TODO: handle varargin
-    if (in.size() > macrodef->getRhs())
-    {
-        return false;
-    }
 
-    std::vector<TIType> completeIn;
-    if (!PolymorphicMacroCache::getCompleteIn(*macrodef, visitor, in, completeIn))
-    {
-        return false;
-    }
+    PolymorphicMacroCache::PolymorphicMacroCache() : id(1) { }
 
-    MacroSignature signature(*macrodef, out.size(), completeIn);
-    MacroSignMap::iterator i = signatures.find(signature);
-    if (i == signatures.end())
+    PolymorphicMacroCache::~PolymorphicMacroCache() { }
+    
+    const bool PolymorphicMacroCache::getOutTypes(AnalysisVisitor & visitor, MacroDef * macrodef, std::vector<TIType> & in, std::vector<TIType> & out, uint64_t & functionId)
     {
-        i = signatures.emplace(signature, 0).first;
-    }
-
-    CompleteMacroSignature & cms = i->second;
-    std::vector<GVN::Value *> values;
-    std::vector<const MultivariatePolynomial *> polys;
-    for (auto & t : completeIn)
-    {
-        if (t.isscalar())
+        // TODO: handle varargin
+        if (in.size() > macrodef->getRhs())
         {
-            GVN::Value * v = t.rows.getValue();
-            values.emplace_back(v);
-            polys.emplace_back(v->poly);
+            return false;
         }
-        else
+
+        std::vector<TIType> completeIn;
+        if (!PolymorphicMacroCache::getCompleteIn(*macrodef, visitor, in, completeIn))
         {
-            GVN::Value * v = t.rows.getValue();
-            values.emplace_back(v);
-            polys.emplace_back(v->poly);
-            v = t.cols.getValue();
-            values.emplace_back(v);
-            polys.emplace_back(v->poly);
+            return false;
         }
-    }
 
-    const MacroOut * mout = cms.getOutTypes(visitor, signature, macrodef, visitor.getDM(), in.size(), completeIn, values);
-    if (mout)
-    {
-        std::vector<TIType>::iterator i = out.begin();
-        for (const auto & t : mout->tuple.types)
+        MacroSignature signature(*macrodef, out.size(), completeIn);
+        MacroSignMap::iterator i = signatures.find(signature);
+        if (i == signatures.end())
         {
-            *i = t;
-            GVN::Value * Rv = getValue(t.rows.getValue(), visitor, polys, mout->maxVarId);
-            GVN::Value * Cv = getValue(t.cols.getValue(), visitor, polys, mout->maxVarId);
-            i->rows.setValue(Rv);
-            i->cols.setValue(Cv);
-            i->invalidScalar();
-            ++i;
+            i = signatures.emplace(signature, CompleteMacroSignature(gvn, id)).first;
         }
 
-        //out.assign(mout->tuple.types.begin(), mout->tuple.types.end());
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
+        CompleteMacroSignature & cms = i->second;
+        std::vector<GVN::Value *> values;
+        std::vector<const MultivariatePolynomial *> polys;
+        for (auto & t : completeIn)
+        {
+            if (t.isscalar())
+            {
+                GVN::Value * v = t.rows.getValue();
+                values.emplace_back(v);
+                polys.emplace_back(v->poly);
+            }
+            else
+            {
+                GVN::Value * v = t.rows.getValue();
+                values.emplace_back(v);
+                polys.emplace_back(v->poly);
+                v = t.cols.getValue();
+                values.emplace_back(v);
+                polys.emplace_back(v->poly);
+            }
+        }
 
-bool PolymorphicMacroCache::getCompleteIn(MacroDef & macrodef, AnalysisVisitor & visitor, const std::vector<TIType> & in, std::vector<TIType> & completeIn)
-{
-    for (const auto & ty : in)
-    {
-        if (ty.type == TIType::UNKNOWN)
+        const MacroOut * mout = cms.getOutTypes(visitor, signature, macrodef, visitor.getDM(), in.size(), completeIn, values, functionId);
+        if (mout)
+        {
+            std::vector<TIType>::iterator i = out.begin();
+            for (const auto & t : mout->tuple.types)
+            {
+                *i = t;
+                GVN::Value * Rv = getValue(t.rows.getValue(), visitor, polys, mout->maxVarId);
+                GVN::Value * Cv = getValue(t.cols.getValue(), visitor, polys, mout->maxVarId);
+                i->rows.setValue(Rv);
+                i->cols.setValue(Cv);
+                i->invalidScalar();
+                ++i;
+            }
+
+            //out.assign(mout->tuple.types.begin(), mout->tuple.types.end());
+            return true;
+        }
+        else
         {
             return false;
         }
     }
 
-    const tools::SymbolOrdSet & globals = macrodef.getGlobals();
-    completeIn.reserve(in.size() + globals.size());
-    for (const auto & ty : in)
+    bool PolymorphicMacroCache::getCompleteIn(MacroDef & macrodef, AnalysisVisitor & visitor, const std::vector<TIType> & in, std::vector<TIType> & completeIn)
     {
-        completeIn.emplace_back(ty);
-    }
-
-    const std::vector<symbol::Symbol> & declaredIn = macrodef.getIn();
-    const unsigned int size = declaredIn.size();
-    DataManager & dm = visitor.getDM();
+        for (const auto & ty : in)
+        {
+            if (ty.type == TIType::UNKNOWN)
+            {
+                return false;
+            }
+        }
 
-    if (in.size() < size)
-    {
-        // we have less rhs than declared rhs:
-        // function foo(x,y,z)...endfunction
-        // called with foo(x) so y and z are globals
-        for (unsigned int i = in.size(); i < size; ++i)
+        const tools::SymbolOrdSet & globals = macrodef.getGlobals();
+        completeIn.reserve(in.size() + globals.size());
+        for (const auto & ty : in)
         {
-            completeIn.emplace_back(dm.getType(declaredIn[i]));
+            completeIn.emplace_back(ty);
         }
-    }
 
-    for (const auto & sym : globals)
-    {
-        TIType ty = dm.getType(sym, /* global */ true);
-        completeIn.emplace_back(ty);
-        if (ty.type == TIType::UNKNOWN)
+        const std::vector<symbol::Symbol> & declaredIn = macrodef.getIn();
+        const unsigned int size = declaredIn.size();
+        DataManager & dm = visitor.getDM();
+
+        if (in.size() < size)
         {
-            return false;
+            // we have less rhs than declared rhs:
+            // function foo(x,y,z)...endfunction
+            // called with foo(x) so y and z are globals
+            for (unsigned int i = in.size(); i < size; ++i)
+            {
+                completeIn.emplace_back(dm.getType(declaredIn[i]));
+            }
         }
-    }
 
-    return true;
-}
+        for (const auto & sym : globals)
+        {
+            TIType ty = dm.getType(sym, /* global */ true);
+            completeIn.emplace_back(ty);
+            if (ty.type == TIType::UNKNOWN)
+            {
+                return false;
+            }
+        }
 
+        return true;
+    }
 
-GVN::Value * PolymorphicMacroCache::getValue(const GVN::Value * value, AnalysisVisitor & visitor, const std::vector<const MultivariatePolynomial *> & polys, const int maxVarId) const
-{
-    if (value->poly->containsVarsGEq(maxVarId + 1))
+    GVN::Value * PolymorphicMacroCache::getValue(const GVN::Value * value, AnalysisVisitor & visitor, const std::vector<const MultivariatePolynomial *> & polys, const int maxVarId) const
     {
-        // we translate variables with an id which could conflict with ids in the poly
-        MultivariatePolynomial mp1 = value->poly->translateVariables(visitor.getGVN().getCurrentValue() + 1, maxVarId + 1);
-        MultivariatePolynomial mp2 = mp1.eval(polys);
-        if (mp2.containsVarsGEq(visitor.getGVN().getCurrentValue() + 1))
+        if (value->poly->containsVarsGEq(maxVarId + 1))
         {
-            // after evaluation, we have always values coming from the function block GVN
-            return visitor.getGVN().getValue();
+            // we translate variables with an id which could conflict with ids in the poly
+            MultivariatePolynomial mp1 = value->poly->translateVariables(visitor.getGVN().getCurrentValue() + 1, maxVarId + 1);
+            MultivariatePolynomial mp2 = mp1.eval(polys);
+            if (mp2.containsVarsGEq(visitor.getGVN().getCurrentValue() + 1))
+            {
+                // after evaluation, we have always values coming from the function block GVN
+                return visitor.getGVN().getValue();
+            }
+            else
+            {
+                return visitor.getGVN().getValue(mp2);
+            }
         }
         else
         {
-            return visitor.getGVN().getValue(mp2);
+            // the out poly is only an expression of the in values
+            MultivariatePolynomial mp = value->poly->eval(polys);
+            return visitor.getGVN().getValue(mp);
         }
     }
-    else
+
+    std::wostream & operator<<(std::wostream & out, const PolymorphicMacroCache & pmc)
     {
-        // the out poly is only an expression of the in values
-        MultivariatePolynomial mp = value->poly->eval(polys);
-        return visitor.getGVN().getValue(mp);
+        out << L"Macro cache" << "\n";
+        tools::printMap(pmc.signatures, out, true);
+        return out;
     }
-}
 
 } // namespace analysis
index e5b9707..f61da02 100644 (file)
@@ -49,13 +49,11 @@ void AnalysisVisitor::visit(ast::CallExp & e, const unsigned int lhs)
             {
                 if (getCM().checkGlobalConstant(sym) && it->second.get()->analyze(*this, lhs, e))
                 {
-                    pushCall(e.getDecorator().getCall());
                     return;
                 }
             }
 
             visitArguments(name, lhs, info.type, e, e.getArgs());
-            pushCall(e.getDecorator().getCall());
         }
         else
         {
index 9ce29ae..87dfc5c 100644 (file)
@@ -17,8 +17,6 @@
 namespace analysis
 {
 
-
-
 void AnalysisVisitor::visit(ast::OpExp & e)
 {
     logger.log(L"OpExp", e.getLocation());