GVN fixed about non managed Exp
[scilab.git] / scilab / modules / ast / includes / analysis / gvn / TestGVNVisitor.hxx
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 #ifndef __TEST_GVN_VISITOR_HXX__
17 #define __TEST_GVN_VISITOR_HXX__
18
19 #include <iostream>
20 #include <string>
21 #include <map>
22
23 #include "visitor.hxx"
24 #include "execvisitor.hxx"
25 #include "allexp.hxx"
26 #include "allvar.hxx"
27 //#include "Chrono.hxx"
28 #include "GVN.hxx"
29
30 namespace analysis
31 {
32
33 class TestGVNVisitor : public ast::Visitor /*, public Chrono */
34 {
35
36     GVN gvn;
37     const GVN::Value * _result;
38
39 public:
40
41     TestGVNVisitor() : _result(nullptr)
42     {
43         //start_chrono();
44     }
45
46     virtual ~TestGVNVisitor()
47     {
48     }
49
50     virtual TestGVNVisitor* clone()
51     {
52         return new TestGVNVisitor();
53     }
54
55     inline void print_info()
56     {
57         //stop_chrono();
58         std::wcout << L"GVN: " << /* *static_cast<Chrono *>(this) << */ std::endl;
59         std::wcout << gvn << std::endl;
60     }
61
62     inline void setResult(const GVN::Value * val)
63     {
64         _result = val;
65     }
66
67     inline const GVN::Value* getResult()
68     {
69         return _result;
70     }
71
72     inline std::map<std::wstring, uint64_t> getSymMap() const
73     {
74         return gvn.getSymMap();
75     }
76
77 private:
78
79     void visit(ast::SimpleVar & e)
80     {
81         setResult(gvn.getValue(e.getSymbol()));
82     }
83
84     void visit(ast::DollarVar & /*e*/)
85     {
86         // nothing to do
87     }
88
89     void visit(ast::ColonVar & /*e*/)
90     {
91         // nothing to do
92     }
93
94     void visit(ast::ArrayListVar & /*e*/)
95     {
96     }
97
98     void visit(ast::DoubleExp & e)
99     {
100         setResult(gvn.getValue(e.getValue()));
101     }
102
103     void visit(ast::BoolExp & /*e*/)
104     {
105     }
106
107     void visit(ast::StringExp & /*e*/)
108     {
109     }
110
111     void visit(ast::CommentExp & /*e*/)
112     {
113         // ignored
114     }
115
116     void visit(ast::NilExp & /*e*/)
117     {
118         // nothing to do
119     }
120
121     void visit(ast::CallExp & /*e*/)
122     {
123     }
124
125     void visit(ast::CellCallExp & /*e*/)
126     {
127     }
128
129     void visit(ast::OpExp & e)
130     {
131         e.getLeft().accept(*this);
132         const GVN::Value* LV = getResult();
133         e.getRight().accept(*this);
134         const GVN::Value* RV = getResult();
135
136         switch (e.getOper())
137         {
138             case ast::OpExp::plus:
139                 setResult(gvn.getValue(OpValue::PLUS, *LV, *RV));
140                 break;
141             case ast::OpExp::minus:
142                 setResult(gvn.getValue(OpValue::MINUS, *LV, *RV));
143                 break;
144             case ast::OpExp::unaryMinus:
145                 setResult(gvn.getValue(OpValue::UNARYMINUS, *RV));
146                 break;
147             case ast::OpExp::rdivide:
148                 setResult(gvn.getValue(OpValue::RDIV, *LV, *RV));
149                 break;
150             case ast::OpExp::dotrdivide:
151                 setResult(gvn.getValue(OpValue::DOTRDIV, *LV, *RV));
152                 break;
153             case ast::OpExp::times:
154                 setResult(gvn.getValue(OpValue::TIMES, *LV, *RV));
155                 break;
156             case ast::OpExp::dottimes:
157                 setResult(gvn.getValue(OpValue::DOTTIMES, *LV, *RV));
158                 break;
159             case ast::OpExp::power:
160                 setResult(gvn.getValue(OpValue::POWER, *LV, *RV));
161                 break;
162             case ast::OpExp::dotpower:
163                 setResult(gvn.getValue(OpValue::DOTPOWER, *LV, *RV));
164                 break;
165             case ast::OpExp::eq:
166                 if (LV->value == RV->value)
167                 {
168                     setResult(gvn.getValue(int64_t(1)));
169                 }
170                 else
171                 {
172                     setResult(gvn.getValue(int64_t(0)));
173                 }
174                 break;
175             case ast::OpExp::ne:
176                 if (LV->value != RV->value)
177                 {
178                     setResult(gvn.getValue(int64_t(1)));
179                 }
180                 else
181                 {
182                     setResult(gvn.getValue(int64_t(0)));
183                 }
184                 break;
185             case ast::OpExp::ldivide:
186             case ast::OpExp::dotldivide:
187             case ast::OpExp::krontimes:
188             case ast::OpExp::kronrdivide:
189             case ast::OpExp::kronldivide:
190             case ast::OpExp::controltimes:
191             case ast::OpExp::controlrdivide:
192             case ast::OpExp::controlldivide:
193             case ast::OpExp::lt:
194             case ast::OpExp::le:
195             case ast::OpExp::gt:
196             case ast::OpExp::ge:
197             case ast::OpExp::logicalAnd:
198             case ast::OpExp::logicalOr:
199             case ast::OpExp::logicalShortCutAnd:
200             case ast::OpExp::logicalShortCutOr:
201                 std::cerr << "TestGVNVisitor: unsupported ast::OpExp" << std::endl;
202                 break;
203         }
204     }
205
206     void visit(ast::LogicalOpExp & /*e*/)
207     {
208     }
209
210     void visit(ast::AssignExp & e)
211     {
212         if (e.getLeftExp().isSimpleVar())
213         {
214             ast::SimpleVar & Lvar = static_cast<ast::SimpleVar &>(e.getLeftExp());
215             symbol::Symbol & Lsym = Lvar.getSymbol();
216
217             if (e.getRightExp().isCallExp())
218             {
219                 ast::CallExp & ce = static_cast<ast::CallExp &>(e.getRightExp());
220                 std::unordered_map<uint64_t, const MultivariatePolynomial *> args;
221                 const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
222                 for (auto & arg : ce.getExps())
223                 {
224                     if (arg->isAssignExp())
225                     {
226                         ast::AssignExp & ae = static_cast<ast::AssignExp &>(*arg);
227                         const symbol::Symbol & _Lsym = static_cast<ast::SimpleVar &>(ae.getLeftExp()).getSymbol();
228                         ae.getRightExp().accept(*this);
229                         args[gvn.getValue(_Lsym)->value] = getResult()->poly;
230                     }
231                 }
232                 const GVN::Value * callee = gvn.getValue(sym);
233                 gvn.setValue(Lsym, callee->poly->eval(args));
234             }
235             else
236             {
237                 setResult(nullptr);
238                 e.getRightExp().accept(*this);
239                 const GVN::Value* LV = getResult();
240                 if(LV)
241                 {
242                     gvn.setValue(Lsym, *LV);
243                 }
244             }
245         }
246     }
247
248     void visit(ast::IfExp & /*e*/)
249     {
250     }
251
252     void visit(ast::WhileExp & /*e*/)
253     {
254     }
255
256     void visit(ast::ForExp & /*e*/)
257     {
258     }
259
260     void visit(ast::BreakExp & /*e*/)
261     {
262         // nothing to do
263     }
264
265     void visit(ast::ContinueExp & /*e*/)
266     {
267         // nothing to do
268     }
269
270     void visit(ast::TryCatchExp & /*e*/)
271     {
272     }
273
274     void visit(ast::SelectExp & /*e*/)
275     {
276     }
277
278     void visit(ast::CaseExp & /*e*/)
279     {
280     }
281
282     void visit(ast::ReturnExp & /*e*/)
283     {
284     }
285
286     void visit(ast::FieldExp & /*e*/)
287     {
288     }
289
290     void visit(ast::NotExp & /*e*/)
291     {
292     }
293
294     void visit(ast::TransposeExp & /*e*/)
295     {
296     }
297
298     void visit(ast::MatrixExp & /*e*/)
299     {
300     }
301
302     void visit(ast::MatrixLineExp & /*e*/)
303     {
304     }
305
306     void visit(ast::CellExp & /*e*/)
307     {
308     }
309
310     void visit(ast::SeqExp & e)
311     {
312         for (auto exp : e.getExps())
313         {
314             exp->accept(*this);
315         }
316     }
317
318     void visit(ast::ArrayListExp & /*e*/)
319     {
320     }
321
322     void visit(ast::AssignListExp & /*e*/)
323     {
324     }
325
326     void visit(ast::VarDec & /*e*/)
327     {
328     }
329
330     void visit(ast::FunctionDec & /*e*/)
331     {
332     }
333
334     void visit(ast::ListExp & /*e*/)
335     {
336     }
337
338     void visit(ast::OptimizedExp & /*e*/)
339     {
340     }
341
342     void visit(ast::MemfillExp & /*e*/)
343     {
344     }
345
346     void visit(ast::DAXPYExp & /*e*/)
347     {
348     }
349
350     void visit(ast::IntSelectExp & /*e*/)
351     {
352     }
353
354     void visit(ast::StringSelectExp & /*e*/)
355     {
356     }
357 };
358
359 } // namespace analysis
360
361 #endif // __TEST_GVN_VISITOR_HXX__