dfd3d9491896bd7b1aa6b61936df28b228426a99
[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             }
171             case ast::OpExp::dotrdivide:
172             {
173                 if (gvnL->poly->isDivisibleBy(*gvnR->poly))
174                 {
175                     if (LisInt)
176                     {
177                         resL.getConstant() = gvnL;
178                     }
179                     if (RisInt)
180                     {
181                         resR.getConstant() = gvnR;
182                     }
183                     Result & res = oe.getDecorator().setResult(typ);
184                     res.getConstant() = getGVN().getValue(OpValue::DOTRDIV, *gvnL, *gvnR);
185                     oe.getDecorator().safe = true;
186                     setResult(res);
187                     return true;
188                 }
189             }
190             }
191         }
192
193         return false;
194     }
195 }