700438bde3afa13d07da3fd1021efe919292f76f
[scilab.git] / scilab / modules / ast / src / cpp / analysis / OperGVNValues.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "AnalysisVisitor.hxx"
14 #include "tools.hxx"
15
16 namespace analysis
17 {
18 bool AnalysisVisitor::operGVNValues(ast::OpExp & oe)
19 {
20     Result & resL = oe.getLeft().getDecorator().getResult();
21     Result & resR = oe.getRight().getDecorator().getResult();
22     const ConstantValue & valL = resL.getConstant();
23     const ConstantValue & valR = resR.getConstant();
24     GVN::Value * gvnL = nullptr;
25     GVN::Value * gvnR = nullptr;
26     bool LisInt = false;
27     bool RisInt = false;
28
29     if (valL.getKind() == ConstantValue::GVNVAL)
30     {
31         gvnL = valL.getGVNValue();
32     }
33     else
34     {
35         double val;
36         if (valL.getDblValue(val) && tools::isAnInt(val))
37         {
38             gvnL = getGVN().getValue(val);
39             LisInt = true;
40         }
41     }
42
43     if (valR.getKind() == ConstantValue::GVNVAL)
44     {
45         gvnR = valR.getGVNValue();
46     }
47     else
48     {
49         double val;
50         if (valR.getDblValue(val) && tools::isAnInt(val))
51         {
52             gvnR = getGVN().getValue(val);
53             RisInt = true;
54         }
55     }
56
57     if (gvnL && gvnR)
58     {
59         TIType typ(getGVN(), TIType::DOUBLE, 1, 1);
60
61         switch (oe.getOper())
62         {
63             case ast::OpExp::plus:
64             {
65                 if (LisInt)
66                 {
67                     resL.getConstant() = gvnL;
68                 }
69                 if (RisInt)
70                 {
71                     resR.getConstant() = gvnR;
72                 }
73                 Result & res = oe.getDecorator().setResult(typ);
74                 res.getConstant() = getGVN().getValue(OpValue::PLUS, *gvnL, *gvnR);
75                 oe.getDecorator().safe = true;
76                 setResult(res);
77                 return true;
78             }
79             case ast::OpExp::minus:
80             {
81                 if (LisInt)
82                 {
83                     resL.getConstant() = gvnL;
84                 }
85                 if (RisInt)
86                 {
87                     resR.getConstant() = gvnR;
88                 }
89                 Result & res = oe.getDecorator().setResult(typ);
90                 res.getConstant() = getGVN().getValue(OpValue::MINUS, *gvnL, *gvnR);
91                 oe.getDecorator().safe = true;
92                 setResult(res);
93                 return true;
94                 break;
95             }
96             case ast::OpExp::times:
97             {
98                 if (LisInt)
99                 {
100                     resL.getConstant() = gvnL;
101                 }
102                 if (RisInt)
103                 {
104                     resR.getConstant() = gvnR;
105                 }
106                 Result & res = oe.getDecorator().setResult(typ);
107                 res.getConstant() = getGVN().getValue(OpValue::TIMES, *gvnL, *gvnR);
108                 oe.getDecorator().safe = true;
109                 setResult(res);
110                 return true;
111             }
112             case ast::OpExp::dottimes:
113             {
114                 if (LisInt)
115                 {
116                     resL.getConstant() = gvnL;
117                 }
118                 if (RisInt)
119                 {
120                     resR.getConstant() = gvnR;
121                 }
122                 Result & res = oe.getDecorator().setResult(typ);
123                 res.getConstant() = getGVN().getValue(OpValue::DOTTIMES, *gvnL, *gvnR);
124                 oe.getDecorator().safe = true;
125                 setResult(res);
126                 return true;
127             }
128             case ast::OpExp::power:
129             {
130                 Result & res = oe.getDecorator().setResult(typ);
131                 res.getConstant() = getGVN().getValue(OpValue::POWER, *gvnL, *gvnR);
132                 oe.getDecorator().safe = true;
133                 setResult(res);
134                 return true;
135             }
136             case ast::OpExp::dotpower:
137             {
138                 if (LisInt)
139                 {
140                     resL.getConstant() = gvnL;
141                 }
142                 if (RisInt)
143                 {
144                     resR.getConstant() = gvnR;
145                 }
146                 Result & res = oe.getDecorator().setResult(typ);
147                 res.getConstant() = getGVN().getValue(OpValue::DOTPOWER, *gvnL, *gvnR);
148                 oe.getDecorator().safe = true;
149                 setResult(res);
150                 return true;
151             }
152             case ast::OpExp::rdivide:
153             {
154                 if (gvnL->poly->isDivisibleBy(*gvnR->poly))
155                 {
156                     if (LisInt)
157                     {
158                         resL.getConstant() = gvnL;
159                     }
160                     if (RisInt)
161                     {
162                         resR.getConstant() = gvnR;
163                     }
164                     Result & res = oe.getDecorator().setResult(typ);
165                     res.getConstant() = getGVN().getValue(OpValue::RDIV, *gvnL, *gvnR);
166                     oe.getDecorator().safe = true;
167                     setResult(res);
168                     return true;
169                 }
170                 break;
171             }
172             case ast::OpExp::dotrdivide:
173             {
174                 if (gvnL->poly->isDivisibleBy(*gvnR->poly))
175                 {
176                     if (LisInt)
177                     {
178                         resL.getConstant() = gvnL;
179                     }
180                     if (RisInt)
181                     {
182                         resR.getConstant() = gvnR;
183                     }
184                     Result & res = oe.getDecorator().setResult(typ);
185                     res.getConstant() = getGVN().getValue(OpValue::DOTRDIV, *gvnL, *gvnR);
186                     oe.getDecorator().safe = true;
187                     setResult(res);
188                     return true;
189                 }
190             }
191         }
192     }
193
194     return false;
195 }
196 }