1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 
16 #include "AnalysisVisitor.hxx"
17 #include "data/CompleteMacroSignature.hxx"
18 #include "data/FunctionBlock.hxx"
19 #include "data/DataManager.hxx"
20 #include "data/GlobalsCollector.hxx"
21 
22 namespace analysis
23 {
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)24 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)
25 {
26     for (const auto & mpcmo : outMap)
27     {
28         if (mpcmo.verified.check(visitor.getGVN(), values) == InferenceConstraint::RESULT_TRUE && ConstraintManager::checkGlobalConstants(mpcmo.globalConstants))
29         {
30             for (const auto & set : mpcmo.unverified)
31             {
32                 if (set.check(visitor.getGVN(), values) != InferenceConstraint::RESULT_FALSE)
33                 {
34                     return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
35                 }
36             }
37             functionId = mpcmo.id;
38             return &mpcmo.out;
39         }
40     }
41 
42     return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
43 }
44 
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)45 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)
46 {
47     if (signature.lhs <= macrodef->getLhs())
48     {
49         visitor.getLogger().log(L"Visit macro ", macrodef->getName());
50         dm.addBlock(Block::MACRO, &macrodef->getBody());
51         FunctionBlock & fblock = *static_cast<FunctionBlock *>(dm.getCurrent());
52         fblock.setName(macrodef->getName());
53         fblock.setLhsRhs(signature.lhs, rhs);
54         fblock.setInOut(macrodef, rhs, in);
55         fblock.setGlobals(macrodef->getGlobals());
56         if (!fblock.addIn(signature.tuple, values))
57         {
58             dm.finalizeBlock();
59             return nullptr;
60         }
61 
62         fblock.getExp()->accept(visitor);
63         dm.finalizeBlock();
64         //std::wcerr << fblock << std::endl;
65         const auto p = outMap.emplace(id++, fblock.getVerifiedConstraints(), fblock.getUnverifiedConstraints(), fblock.getGlobalConstants(), fblock.getOuts(*this));
66         fblock.setFunctionId(p.first->id);
67         functionId = p.first->id;
68         visitor.emitFunctionBlock(fblock);
69 
70         //std::wcerr << *this << std::endl;
71 
72         return &p.first->out;
73     }
74 
75     return nullptr;
76 }
77 
operator <<(std::wostream & out,const CompleteMacroSignature & cms)78 std::wostream & operator<<(std::wostream & out, const CompleteMacroSignature & cms)
79 {
80     out << L"Complete Macro Cache:\n";
81     for (const auto & mpcmo : cms.outMap)
82     {
83         out << L" * Verified constraints: " << mpcmo.verified << L"\n"
84             << L" * Unverified constraints: ";
85         tools::printSet(mpcmo.unverified, out);
86         out << L"\n"
87             << L" * Globals: ";
88         tools::printSet(mpcmo.globalConstants, out);
89         out << L"\n"
90             << L"   => " << mpcmo.out.tuple << L"\n";
91     }
92     return out;
93 }
94 
95 } // namespace analysis
96